You need to see the asm output to understand. The following will show what is happening.
Although the bit access looks like it should only be dealing with a single bit, it has to read the peripheral register, modify the temp copy to set 1 particular bit, then store it back to the peripheral register. When reading the T0IR register, all bits (flags) are being read, a single bit is set via an orr instruction, then the value is written back- but these flags are cleared by writing its bit with a 1 so any other flag that was set now has its bit cleared because any bit that was 1 when read also writes that same value back.
The answer is to simply write a 1 to a bit position you want cleared via a single register write. Writing a bit with a 0 has no effect.
So anytime you find a register that has flags, in many cases they tend to be write 1 to clear, which means you will not be writing individual bits, but the whole register.
Clearing flags unintentionally will result in strange problems. Not sure if it is your problem currently, but if corrected it will at least be 1 less than you had before.
https://godbolt.org/z/EWfeTv#include <stdint.h>
typedef struct { uint32_t MR0INT : 1; } bit_t;
#define T0IR_bit (*(volatile bit_t*)0xE0004000)
#define T0IR (*(volatile uint32_t*)0xE0004000)
int main(){
T0IR_bit.MR0INT = 1; //incorrect
T0IR = 1<<0; //correct
while(1);
}
/*
main:
//T0IR_bit.MR0INT = 1;
ldr r3, .L3
ldrb r2, [r3] //read
orr r2, r2, #1 //modify -> |= 1
strb r2, [r3] //write
//T0IR = 1<<0;
mov r2, #1 //bit0 is all we want cleared
str r2, [r3] //a single register write will result in only bit0 cleared
.L2:
b .L2
.L3:
.word -536854528
*/