return SDValue();
}
-/// Optimize x == -y --> x+y == 0
-/// x != -y --> x+y != 0
static SDValue combineSetCC(SDNode *N, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
EVT VT = N->getValueType(0);
SDLoc DL(N);
- if ((CC == ISD::SETNE || CC == ISD::SETEQ) && LHS.getOpcode() == ISD::SUB)
- if (isNullConstant(LHS.getOperand(0)) && LHS.hasOneUse()) {
- SDValue addV = DAG.getNode(ISD::ADD, DL, LHS.getValueType(), RHS,
- LHS.getOperand(1));
- return DAG.getSetCC(DL, N->getValueType(0), addV,
- DAG.getConstant(0, DL, addV.getValueType()), CC);
+ if (CC == ISD::SETNE || CC == ISD::SETEQ) {
+ EVT OpVT = LHS.getValueType();
+ // 0-x == y --> x+y == 0
+ // 0-x != y --> x+y != 0
+ if (LHS.getOpcode() == ISD::SUB && isNullConstant(LHS.getOperand(0)) &&
+ LHS.hasOneUse()) {
+ SDValue Add = DAG.getNode(ISD::ADD, DL, OpVT, RHS, LHS.getOperand(1));
+ return DAG.getSetCC(DL, VT, Add, DAG.getConstant(0, DL, OpVT), CC);
}
- if ((CC == ISD::SETNE || CC == ISD::SETEQ) && RHS.getOpcode() == ISD::SUB)
- if (isNullConstant(RHS.getOperand(0)) && RHS.hasOneUse()) {
- SDValue addV = DAG.getNode(ISD::ADD, DL, RHS.getValueType(), LHS,
- RHS.getOperand(1));
- return DAG.getSetCC(DL, N->getValueType(0), addV,
- DAG.getConstant(0, DL, addV.getValueType()), CC);
+ // x == 0-y --> x+y == 0
+ // x != 0-y --> x+y != 0
+ if (RHS.getOpcode() == ISD::SUB && isNullConstant(RHS.getOperand(0)) &&
+ RHS.hasOneUse()) {
+ SDValue Add = DAG.getNode(ISD::ADD, DL, OpVT, LHS, RHS.getOperand(1));
+ return DAG.getSetCC(DL, VT, Add, DAG.getConstant(0, DL, OpVT), CC);
}
+ }
if (VT.getScalarType() == MVT::i1 &&
(CC == ISD::SETNE || CC == ISD::SETEQ || ISD::isSignedIntSetCC(CC))) {
-; RUN: llc < %s -march=x86-64 | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
; rdar://11245199
; PR12545
-define void @f(i32 %x, i32 %y) nounwind uwtable ssp {
-entry:
-; CHECK-LABEL: f:
-; CHECK-NOT: neg
-; CHECK: add
+
+declare void @g()
+
+define void @neg_cmp(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: neg_cmp:
+; CHECK: # BB#0:
+; CHECK-NEXT: addl %esi, %edi
+; CHECK-NEXT: jne .LBB0_1
+; CHECK-NEXT: # BB#2: # %if.then
+; CHECK-NEXT: jmp g # TAILCALL
+; CHECK-NEXT: .LBB0_1: # %if.end
+; CHECK-NEXT: retq
%sub = sub i32 0, %y
%cmp = icmp eq i32 %x, %sub
br i1 %cmp, label %if.then, label %if.end
-if.then: ; preds = %entry
+if.then:
tail call void @g() nounwind
br label %if.end
-if.end: ; preds = %if.then, %entry
+if.end:
+ ret void
+}
+
+define void @neg_cmp_commuted(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: neg_cmp_commuted:
+; CHECK: # BB#0:
+; CHECK-NEXT: addl %esi, %edi
+; CHECK-NEXT: jne .LBB1_1
+; CHECK-NEXT: # BB#2: # %if.then
+; CHECK-NEXT: jmp g # TAILCALL
+; CHECK-NEXT: .LBB1_1: # %if.end
+; CHECK-NEXT: retq
+ %sub = sub i32 0, %y
+ %cmp = icmp eq i32 %sub, %x
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @g() nounwind
+ br label %if.end
+
+if.end:
ret void
}
-declare void @g()