[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