[llvm] r245641 - AArch64: Fix cmp;ccmp ordering

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 16:33:34 PDT 2015


Author: matze
Date: Thu Aug 20 18:33:34 2015
New Revision: 245641

URL: http://llvm.org/viewvc/llvm-project?rev=245641&view=rev
Log:
AArch64: Fix cmp;ccmp ordering

When producing conditional compare sequences for or operations we need
to negate the operands and the finally tested flags. The thing is if we negate
the finally tested flags this equals a logical negation of all previously
emitted expressions. There was a case missing where we have to order OR
expressions so they get emitted first.

This fixes http://llvm.org/PR24459

Modified:
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll

Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=245641&r1=245640&r2=245641&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Thu Aug 20 18:33:34 2015
@@ -1374,10 +1374,17 @@ static SDValue emitConjunctionDisjunctio
     if (!CanPushNegateL && !CanPushNegateR)
       return SDValue();
     // Order the side where we can push the negate through to LHS.
-    if (!CanPushNegateL && CanPushNegateR) {
+    if (!CanPushNegateL && CanPushNegateR)
+      std::swap(LHS, RHS);
+  } else {
+    bool NeedsNegOutL = LHS->getOpcode() == ISD::OR;
+    bool NeedsNegOutR = RHS->getOpcode() == ISD::OR;
+    if (NeedsNegOutL && NeedsNegOutR)
+      return SDValue();
+    // Order the side where we need to negate the output flags to RHS so it
+    // gets emitted first.
+    if (NeedsNegOutL)
       std::swap(LHS, RHS);
-      CanPushNegateL = true;
-    }
   }
 
   // Emit RHS. If we want to negate the tree we only need to push a negate

Modified: llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll?rev=245641&r1=245640&r2=245641&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/arm64-ccmp.ll Thu Aug 20 18:33:34 2015
@@ -337,9 +337,9 @@ define i16 @select_complicated(double %v
 
 ; CHECK-LABEL: gccbug
 define i64 @gccbug(i64 %x0, i64 %x1) {
-; CHECK: cmp x1, #0
-; CHECK-NEXT: ccmp x0, #2, #0, eq
+; CHECK: cmp x0, #2
 ; CHECK-NEXT: ccmp x0, #4, #4, ne
+; CHECK-NEXT: ccmp x1, #0, #0, eq
 ; CHECK-NEXT: orr w[[REGNUM:[0-9]+]], wzr, #0x1
 ; CHECK-NEXT: cinc x0, x[[REGNUM]], eq
 ; CHECK-NEXT: ret
@@ -373,6 +373,22 @@ define i32 @select_ororand(i32 %w0, i32
   ret i32 %sel
 }
 
+; CHECK-LABEL: select_andor
+define i32 @select_andor(i32 %v1, i32 %v2, i32 %v3) {
+; CHECK: cmp w1, w2
+; CHECK-NEXT: ccmp w0, #0, #4, lt
+; CHECK-NEXT: ccmp w0, w1, #0, eq
+; CHECK-NEXT: csel w0, w0, w1, eq
+; CHECK-NEXT: ret
+  %c0 = icmp eq i32 %v1, %v2
+  %c1 = icmp sge i32 %v2, %v3
+  %c2 = icmp eq i32 %v1, 0
+  %or = or i1 %c2, %c1
+  %and = and i1 %or, %c0
+  %sel = select i1 %and, i32 %v1, i32 %v2
+  ret i32 %sel
+}
+
 ; CHECK-LABEL: select_noccmp1
 define i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
 ; CHECK-NOT: CCMP




More information about the llvm-commits mailing list