Skip to content

Commit

Permalink
AArch64: Fix cmp;ccmp ordering
Browse files Browse the repository at this point in the history
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245641 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
MatzeB committed Aug 20, 2015
1 parent 05b3080 commit 57970eb
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
13 changes: 10 additions & 3 deletions lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1374,10 +1374,17 @@ static SDValue emitConjunctionDisjunctionTree(SelectionDAG &DAG, SDValue Val,
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
Expand Down
20 changes: 18 additions & 2 deletions test/CodeGen/AArch64/arm64-ccmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ define i16 @select_complicated(double %v1, double %v2, i16 %a, i16 %b) {

; 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
Expand Down Expand Up @@ -373,6 +373,22 @@ define i32 @select_ororand(i32 %w0, i32 %w1, i32 %w2, i32 %w3) {
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
Expand Down

0 comments on commit 57970eb

Please sign in to comment.