forked from OSchip/llvm-project
Make isSetCCEquivalent respect the TargetBooleanContents
llvm-svn: 205336
This commit is contained in:
parent
6310c3f667
commit
e407ae9846
|
@ -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);
|
LHS = N.getOperand(0);
|
||||||
RHS = N.getOperand(1);
|
RHS = N.getOperand(1);
|
||||||
CC = N.getOperand(4);
|
CC = N.getOperand(4);
|
||||||
return true;
|
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;
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue