Make isSetCCEquivalent respect the TargetBooleanContents

llvm-svn: 205336
This commit is contained in:
Matt Arsenault 2014-04-01 18:13:26 +00:00
parent 6310c3f667
commit e407ae9846
2 changed files with 51 additions and 19 deletions

View File

@ -290,6 +290,11 @@ namespace {
bool NotExtCompare = false); bool NotExtCompare = false);
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
SDLoc DL, bool foldBooleans = true); SDLoc DL, bool foldBooleans = true);
bool isSetCCEquivalent(SDValue N, SDValue &LHS, SDValue &RHS,
SDValue &CC) const;
bool isOneUseSetCC(SDValue N) const;
SDValue SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp, SDValue SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
unsigned HiOp); unsigned HiOp);
SDValue CombineConsecutiveLoads(SDNode *N, EVT VT); SDValue CombineConsecutiveLoads(SDNode *N, EVT VT);
@ -597,37 +602,35 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG,
} }
} }
// isSetCCEquivalent - Return true if this node is a setcc, or is a select_cc // isSetCCEquivalent - Return true if this node is a setcc, or is a select_cc
// that selects between the values 1 and 0, making it equivalent to a setcc. // that selects between the target values used for true and false, making it
// Also, set the incoming LHS, RHS, and CC references to the appropriate // equivalent to a setcc. Also, set the incoming LHS, RHS, and CC references to
// nodes based on the type of node we are checking. This simplifies life a // the appropriate nodes based on the type of node we are checking. This
// bit for the callers. // simplifies life a bit for the callers.
static bool isSetCCEquivalent(SDValue N, SDValue &LHS, SDValue &RHS, bool DAGCombiner::isSetCCEquivalent(SDValue N, SDValue &LHS, SDValue &RHS,
SDValue &CC) { SDValue &CC) const {
if (N.getOpcode() == ISD::SETCC) { if (N.getOpcode() == ISD::SETCC) {
LHS = N.getOperand(0); LHS = N.getOperand(0);
RHS = N.getOperand(1); RHS = N.getOperand(1);
CC = N.getOperand(2); CC = N.getOperand(2);
return true; return true;
} }
if (N.getOpcode() == ISD::SELECT_CC &&
N.getOperand(2).getOpcode() == ISD::Constant && if (N.getOpcode() != ISD::SELECT_CC ||
N.getOperand(3).getOpcode() == ISD::Constant && !TLI.isConstTrueVal(N.getOperand(2).getNode()) ||
cast<ConstantSDNode>(N.getOperand(2))->getAPIntValue() == 1 && !TLI.isConstFalseVal(N.getOperand(3).getNode()))
cast<ConstantSDNode>(N.getOperand(3))->isNullValue()) { return false;
LHS = N.getOperand(0);
RHS = N.getOperand(1); LHS = N.getOperand(0);
CC = N.getOperand(4); RHS = N.getOperand(1);
return true; CC = N.getOperand(4);
} return true;
return false;
} }
// isOneUseSetCC - Return true if this is a SetCC-equivalent operation with only // isOneUseSetCC - Return true if this is a SetCC-equivalent operation with only
// one use. If this is true, it allows the users to invert the operation for // one use. If this is true, it allows the users to invert the operation for
// free when it is profitable to do so. // free when it is profitable to do so.
static bool isOneUseSetCC(SDValue N) { bool DAGCombiner::isOneUseSetCC(SDValue N) const {
SDValue N0, N1, N2; SDValue N0, N1, N2;
if (isSetCCEquivalent(N, N0, N1, N2) && N.getNode()->hasOneUse()) if (isSetCCEquivalent(N, N0, N1, N2) && N.getNode()->hasOneUse())
return true; return true;

View File

@ -0,0 +1,29 @@
; EG-LABEL: @and_setcc_setcc_i32
; EG: AND_INT
; EG-NEXT: SETE_INT
define void @and_setcc_setcc_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) {
%cmp1 = icmp eq i32 %a, -1
%cmp2 = icmp eq i32 %b, -1
%and = and i1 %cmp1, %cmp2
%ext = sext i1 %and to i32
store i32 %ext, i32 addrspace(1)* %out, align 4
ret void
}
; EG-LABEL: @and_setcc_setcc_v4i32
; EG: AND_INT
; EG: AND_INT
; EG: SETE_INT
; EG: AND_INT
; EG: SETE_INT
; EG: AND_INT
; EG: SETE_INT
define void @and_setcc_setcc_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %a, <4 x i32> %b) {
%cmp1 = icmp eq <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%cmp2 = icmp eq <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1>
%and = and <4 x i1> %cmp1, %cmp2
%ext = sext <4 x i1> %and to <4 x i32>
store <4 x i32> %ext, <4 x i32> addrspace(1)* %out, align 4
ret void
}