Using the Thumb-2 target we see that ORN ( a | ^b) and BIC (a & ^b) have similar patterns, as we would expect:
defm t2BIC : T2I_bin_irs<“bic”, BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
defm t2ORN : T2I_bin_irs<“orn”, BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
Compiling the following three works as expected:
%tmp1 = xor i32 4294967295, %b ; %tmp2 = or i32 %a, %tmp1 → orn r0, r0, r1
%tmp1 = xor i32 4294967295, %b ; %tmp2 = or i32 %tmp1, %a → orn r0, r0, r1
%tmp = xor i32 %b, 4294967295 ; %tmp1 = and i32 %a, %tmp → bic r0, r0, r1
But this doesn’t:
%tmp = xor i32 %b, 4294967295 ; %tmp1 = and i32 %tmp, %a → eor r1, r1, #4294967295 ; and r0, r1, r0
On the surface it seems that the selector is not commuting the AND operands. I’ve attached the complete test files. I can take a look but I need a pointer to get started.
David
RM_20_BIC.ll (364 Bytes)
RM_112_ORN.ll (366 Bytes)