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);
|
||||
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
|
||||
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,
|
||||
unsigned HiOp);
|
||||
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
|
||||
// that selects between the values 1 and 0, making it equivalent to a setcc.
|
||||
// Also, set the incoming LHS, RHS, and CC references to the appropriate
|
||||
// nodes based on the type of node we are checking. This simplifies life a
|
||||
// bit for the callers.
|
||||
static bool isSetCCEquivalent(SDValue N, SDValue &LHS, SDValue &RHS,
|
||||
SDValue &CC) {
|
||||
// that selects between the target values used for true and false, making it
|
||||
// equivalent to a setcc. Also, set the incoming LHS, RHS, and CC references to
|
||||
// the appropriate nodes based on the type of node we are checking. This
|
||||
// simplifies life a bit for the callers.
|
||||
bool DAGCombiner::isSetCCEquivalent(SDValue N, SDValue &LHS, SDValue &RHS,
|
||||
SDValue &CC) const {
|
||||
if (N.getOpcode() == ISD::SETCC) {
|
||||
LHS = N.getOperand(0);
|
||||
RHS = N.getOperand(1);
|
||||
CC = N.getOperand(2);
|
||||
return true;
|
||||
}
|
||||
if (N.getOpcode() == ISD::SELECT_CC &&
|
||||
N.getOperand(2).getOpcode() == ISD::Constant &&
|
||||
N.getOperand(3).getOpcode() == ISD::Constant &&
|
||||
cast<ConstantSDNode>(N.getOperand(2))->getAPIntValue() == 1 &&
|
||||
cast<ConstantSDNode>(N.getOperand(3))->isNullValue()) {
|
||||
LHS = N.getOperand(0);
|
||||
RHS = N.getOperand(1);
|
||||
CC = N.getOperand(4);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
if (N.getOpcode() != ISD::SELECT_CC ||
|
||||
!TLI.isConstTrueVal(N.getOperand(2).getNode()) ||
|
||||
!TLI.isConstFalseVal(N.getOperand(3).getNode()))
|
||||
return false;
|
||||
|
||||
LHS = N.getOperand(0);
|
||||
RHS = N.getOperand(1);
|
||||
CC = N.getOperand(4);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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
|
||||
// free when it is profitable to do so.
|
||||
static bool isOneUseSetCC(SDValue N) {
|
||||
bool DAGCombiner::isOneUseSetCC(SDValue N) const {
|
||||
SDValue N0, N1, N2;
|
||||
if (isSetCCEquivalent(N, N0, N1, N2) && N.getNode()->hasOneUse())
|
||||
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