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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090625/0706b1cb/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: RM_20_BIC.ll Type: application/octet-stream Size: 364 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090625/0706b1cb/attachment.obj> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090625/0706b1cb/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: RM_112_ORN.ll Type: application/octet-stream Size: 366 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090625/0706b1cb/attachment-0001.obj> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090625/0706b1cb/attachment-0002.html>
On Jun 25, 2009, at 4:38 PM, David Goodwin wrote:> 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.No, isel is trying to commute the AND. See ARMGenDAGISel.inc (auto- generated by tablegen): // Pattern: (and:i32 GPR:i32:$lhs, (xor:i32 t2_so_reg:i32:$rhs, (imm:i32)<<P:Predicate_immAllOnes>>)) // Emits: (t2BICrs:i32 GPR:i32:$lhs, t2_so_reg:i32:$rhs) // Pattern complexity = 19 cost = 1 size = 0 { .. } // Pattern: (and:i32 (xor:i32 t2_so_reg:i32:$rhs, (imm:i32) <<P:Predicate_immAllOnes>>), GPR:i32:$lhs) // Emits: (t2BICrs:i32 GPR:i32:$lhs, t2_so_reg:i32:$rhs) // Pattern complexity = 19 cost = 1 size = 0 { ... } The second one is the commuted version. Looks like the issue is in SelectThumb2ShifterOperandReg. Evan> > David > > <RM_20_BIC.ll> > <RM_112_ORN.ll> > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090625/3d9df62b/attachment.html>
On Jun 25, 2009, at 6:06 PM, Evan Cheng wrote:> > On Jun 25, 2009, at 4:38 PM, David Goodwin wrote: > >> 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. > > No, isel is trying to commute the AND. See ARMGenDAGISel.inc (auto- > generated by tablegen): > > // Pattern: (and:i32 GPR:i32:$lhs, (xor:i32 t2_so_reg:i32:$rhs, > (imm:i32)<<P:Predicate_immAllOnes>>)) > // Emits: (t2BICrs:i32 GPR:i32:$lhs, t2_so_reg:i32:$rhs) > // Pattern complexity = 19 cost = 1 size = 0 > { > .. > } > > > // Pattern: (and:i32 (xor:i32 t2_so_reg:i32:$rhs, (imm:i32) > <<P:Predicate_immAllOnes>>), GPR:i32:$lhs) > // Emits: (t2BICrs:i32 GPR:i32:$lhs, t2_so_reg:i32:$rhs) > // Pattern complexity = 19 cost = 1 size = 0 > { > ... > } > > The second one is the commuted version. Looks like the issue is in > SelectThumb2ShifterOperandReg.Ugh. It should try to match t2BICrr. But someone tblgen is not generating the commuted version. Very strange. I'm take a look. Evan> > Evan > > >> >> David >> >> <RM_20_BIC.ll> >> <RM_112_ORN.ll> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090625/2b47d7a8/attachment.html>