mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Add x86-specific DAG combine to simplify:
x == -y --> x+y == 0 x != -y --> x+y != 0 On x86, the generated code goes from negl %esi cmpl %esi, %edi je .LBB0_2 to addl %esi, %edi je .L4 This case is correctly handled for ARM with "cmn". Patch by Manman Ren. rdar://11245199 PR12545 llvm-svn: 155739
This commit is contained in:
parent
ff5aec2d9d
commit
d627fcbf2a
@ -1223,6 +1223,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
||||
setTargetDAGCombine(ISD::TRUNCATE);
|
||||
setTargetDAGCombine(ISD::UINT_TO_FP);
|
||||
setTargetDAGCombine(ISD::SINT_TO_FP);
|
||||
setTargetDAGCombine(ISD::SETCC);
|
||||
setTargetDAGCombine(ISD::FP_TO_SINT);
|
||||
if (Subtarget->is64Bit())
|
||||
setTargetDAGCombine(ISD::MUL);
|
||||
@ -15000,6 +15001,32 @@ static SDValue PerformZExtCombine(SDNode *N, SelectionDAG &DAG,
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
// Optimize x == -y --> x+y == 0
|
||||
// x != -y --> x+y != 0
|
||||
static SDValue PerformISDSETCCCombine(SDNode *N, SelectionDAG &DAG) {
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
||||
SDValue LHS = N->getOperand(0);
|
||||
SDValue RHS = N->getOperand(1);
|
||||
|
||||
if ((CC == ISD::SETNE || CC == ISD::SETEQ) && LHS.getOpcode() == ISD::SUB)
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(LHS.getOperand(0)))
|
||||
if (C->getAPIntValue() == 0 && LHS.hasOneUse()) {
|
||||
SDValue addV = DAG.getNode(ISD::ADD, N->getDebugLoc(),
|
||||
LHS.getValueType(), RHS, LHS.getOperand(1));
|
||||
return DAG.getSetCC(N->getDebugLoc(), N->getValueType(0),
|
||||
addV, DAG.getConstant(0, addV.getValueType()), CC);
|
||||
}
|
||||
if ((CC == ISD::SETNE || CC == ISD::SETEQ) && RHS.getOpcode() == ISD::SUB)
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS.getOperand(0)))
|
||||
if (C->getAPIntValue() == 0 && RHS.hasOneUse()) {
|
||||
SDValue addV = DAG.getNode(ISD::ADD, N->getDebugLoc(),
|
||||
RHS.getValueType(), LHS, RHS.getOperand(1));
|
||||
return DAG.getSetCC(N->getDebugLoc(), N->getValueType(0),
|
||||
addV, DAG.getConstant(0, addV.getValueType()), CC);
|
||||
}
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
// Optimize RES = X86ISD::SETCC CONDCODE, EFLAG_INPUT
|
||||
static SDValue PerformSETCCCombine(SDNode *N, SelectionDAG &DAG) {
|
||||
unsigned X86CC = N->getConstantOperandVal(0);
|
||||
@ -15230,6 +15257,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
|
||||
case ISD::ZERO_EXTEND: return PerformZExtCombine(N, DAG, DCI, Subtarget);
|
||||
case ISD::SIGN_EXTEND: return PerformSExtCombine(N, DAG, DCI, Subtarget);
|
||||
case ISD::TRUNCATE: return PerformTruncateCombine(N, DAG, DCI);
|
||||
case ISD::SETCC: return PerformISDSETCCCombine(N, DAG);
|
||||
case X86ISD::SETCC: return PerformSETCCCombine(N, DAG);
|
||||
case X86ISD::SHUFP: // Handle all target specific shuffles
|
||||
case X86ISD::PALIGN:
|
||||
|
22
test/CodeGen/X86/neg_cmp.ll
Normal file
22
test/CodeGen/X86/neg_cmp.ll
Normal file
@ -0,0 +1,22 @@
|
||||
; RUN: llc < %s -march=x86-64 | FileCheck %s
|
||||
|
||||
; rdar://11245199
|
||||
; PR12545
|
||||
define void @f(i32 %x, i32 %y) nounwind uwtable ssp {
|
||||
entry:
|
||||
; CHECK: f:
|
||||
; CHECK-NOT: neg
|
||||
; CHECK: add
|
||||
%sub = sub i32 0, %y
|
||||
%cmp = icmp eq i32 %x, %sub
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @g() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end: ; preds = %if.then, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @g()
|
Loading…
Reference in New Issue
Block a user