It must be possible to change instruction sets when branching, in order to call or return from a function in the opposite instruction set.
There are branching instructions that can't change instruction sets for two reasons:
1. A direct branch can have more range if you can assume it's going to a 4-byte aligned address.
2. For compatibility with code written for ARM7DI and other really old pre-thumb processors. Since the original direct branch instructions ignored the bottom two bits of the target address, new direct branch instructions were added rather than change the behavior of the existing ones.
ARM and Thumb are just different encodings of the same instructions, mostly. Having switchover be done implictly via branch instructions is convenient for interworking -- you can link an ARM library with a Thumb application and it all just works, with function addresses having the low bit set for Thumb and clear for ARM. Generated code doesn't need to care beyond making sure it is using the right interworking instructions for call and return.
This is distinct from x86 32 vs 64 bit and ARM 32 vs 64 bit: in both those cases there's really a different processor mode with extra registers and so forth, and switchover is correspondingly more involved.
There are branching instructions that can't change instruction sets for two reasons: 1. A direct branch can have more range if you can assume it's going to a 4-byte aligned address. 2. For compatibility with code written for ARM7DI and other really old pre-thumb processors. Since the original direct branch instructions ignored the bottom two bits of the target address, new direct branch instructions were added rather than change the behavior of the existing ones.