From f30b73b1c6b6ca8453dc61eb3777b4e4414d3839 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 18 Jan 2005 02:52:03 +0000 Subject: [PATCH] Allow setcc operations to have nonbool types. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19656 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 16 +++-- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 68 ++++++++++--------- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 4 +- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 2c0bfb6df86..b975e5859ec 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -565,7 +565,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) Result = DAG.getSetCC(cast(Node)->getCondition(), - Tmp1, Tmp2); + Node->getValueType(0), Tmp1, Tmp2); break; case Promote: Tmp1 = PromoteOp(Node->getOperand(0)); // LHS @@ -605,7 +605,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } Result = DAG.getSetCC(cast(Node)->getCondition(), - Tmp1, Tmp2); + Node->getValueType(0), Tmp1, Tmp2); break; case Expand: SDOperand LHSLo, LHSHi, RHSLo, RHSHi; @@ -617,7 +617,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp1 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); Tmp2 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2); - Result = DAG.getSetCC(cast(Node)->getCondition(), Tmp1, + Result = DAG.getSetCC(cast(Node)->getCondition(), + Node->getValueType(0), Tmp1, DAG.getConstant(0, Tmp1.getValueType())); break; default: @@ -641,11 +642,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // NOTE: on targets without efficient SELECT of bools, we can always use // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) - Tmp1 = DAG.getSetCC(LowCC, LHSLo, RHSLo); + Tmp1 = DAG.getSetCC(LowCC, Node->getValueType(0), LHSLo, RHSLo); Tmp2 = DAG.getSetCC(cast(Node)->getCondition(), - LHSHi, RHSHi); - Result = DAG.getSetCC(ISD::SETEQ, LHSHi, RHSHi); - Result = DAG.getNode(ISD::SELECT, MVT::i1, Result, Tmp1, Tmp2); + Node->getValueType(0), LHSHi, RHSHi); + Result = DAG.getSetCC(ISD::SETEQ, Node->getValueType(0), LHSHi, RHSHi); + Result = DAG.getNode(ISD::SELECT, Tmp1.getValueType(), + Result, Tmp1, Tmp2); break; } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index e40d022ad26..43f13d71fcd 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -341,15 +341,15 @@ SDOperand SelectionDAG::getExternalSymbol(const char *Sym, MVT::ValueType VT) { return SDOperand(N, 0); } -SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1, - SDOperand N2) { +SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, + SDOperand N1, SDOperand N2) { // These setcc operations always fold. switch (Cond) { default: break; case ISD::SETFALSE: - case ISD::SETFALSE2: return getConstant(0, MVT::i1); + case ISD::SETFALSE2: return getConstant(0, VT); case ISD::SETTRUE: - case ISD::SETTRUE2: return getConstant(1, MVT::i1); + case ISD::SETTRUE2: return getConstant(1, VT); } if (ConstantSDNode *N1C = dyn_cast(N1.Val)) @@ -364,16 +364,16 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1, switch (Cond) { default: assert(0 && "Unknown integer setcc!"); - case ISD::SETEQ: return getConstant(C1 == C2, MVT::i1); - case ISD::SETNE: return getConstant(C1 != C2, MVT::i1); - case ISD::SETULT: return getConstant(C1 < C2, MVT::i1); - case ISD::SETUGT: return getConstant(C1 > C2, MVT::i1); - case ISD::SETULE: return getConstant(C1 <= C2, MVT::i1); - case ISD::SETUGE: return getConstant(C1 >= C2, MVT::i1); - case ISD::SETLT: return getConstant((int64_t)C1 < (int64_t)C2, MVT::i1); - case ISD::SETGT: return getConstant((int64_t)C1 > (int64_t)C2, MVT::i1); - case ISD::SETLE: return getConstant((int64_t)C1 <= (int64_t)C2, MVT::i1); - case ISD::SETGE: return getConstant((int64_t)C1 >= (int64_t)C2, MVT::i1); + case ISD::SETEQ: return getConstant(C1 == C2, VT); + case ISD::SETNE: return getConstant(C1 != C2, VT); + case ISD::SETULT: return getConstant(C1 < C2, VT); + case ISD::SETUGT: return getConstant(C1 > C2, VT); + case ISD::SETULE: return getConstant(C1 <= C2, VT); + case ISD::SETUGE: return getConstant(C1 >= C2, VT); + case ISD::SETLT: return getConstant((int64_t)C1 < (int64_t)C2, VT); + case ISD::SETGT: return getConstant((int64_t)C1 > (int64_t)C2, VT); + case ISD::SETLE: return getConstant((int64_t)C1 <= (int64_t)C2, VT); + case ISD::SETGE: return getConstant((int64_t)C1 >= (int64_t)C2, VT); } } else { // Ensure that the constant occurs on the RHS. @@ -387,12 +387,12 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1, switch (Cond) { default: break; // FIXME: Implement the rest of these! - case ISD::SETEQ: return getConstant(C1 == C2, MVT::i1); - case ISD::SETNE: return getConstant(C1 != C2, MVT::i1); - case ISD::SETLT: return getConstant(C1 < C2, MVT::i1); - case ISD::SETGT: return getConstant(C1 > C2, MVT::i1); - case ISD::SETLE: return getConstant(C1 <= C2, MVT::i1); - case ISD::SETGE: return getConstant(C1 > C2, MVT::i1); + case ISD::SETEQ: return getConstant(C1 == C2, VT); + case ISD::SETNE: return getConstant(C1 != C2, VT); + case ISD::SETLT: return getConstant(C1 < C2, VT); + case ISD::SETGT: return getConstant(C1 > C2, VT); + case ISD::SETLE: return getConstant(C1 <= C2, VT); + case ISD::SETGE: return getConstant(C1 >= C2, VT); } } else { // Ensure that the constant occurs on the RHS. @@ -403,12 +403,12 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1, if (N1 == N2) { // We can always fold X == Y for integer setcc's. if (MVT::isInteger(N1.getValueType())) - return getConstant(ISD::isTrueWhenEqual(Cond), MVT::i1); + return getConstant(ISD::isTrueWhenEqual(Cond), VT); unsigned UOF = ISD::getUnorderedFlavor(Cond); if (UOF == 2) // FP operators that are undefined on NaNs. - return getConstant(ISD::isTrueWhenEqual(Cond), MVT::i1); + return getConstant(ISD::isTrueWhenEqual(Cond), VT); if (UOF == ISD::isTrueWhenEqual(Cond)) - return getConstant(UOF, MVT::i1); + return getConstant(UOF, VT); // Otherwise, we can't fold it. However, we can simplify it to SETUO/SETO // if it is not already. Cond = UOF == 0 ? ISD::SETUO : ISD::SETO; @@ -421,30 +421,30 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1, // Simplify (X+Y) == (X+Z) --> Y == Z if (N1.getOpcode() == N2.getOpcode()) { if (N1.getOperand(0) == N2.getOperand(0)) - return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1)); + return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(1)); if (N1.getOperand(1) == N2.getOperand(1)) - return getSetCC(Cond, N1.getOperand(0), N2.getOperand(0)); + return getSetCC(Cond, VT, N1.getOperand(0), N2.getOperand(0)); if (isCommutativeBinOp(N1.getOpcode())) { // If X op Y == Y op X, try other combinations. if (N1.getOperand(0) == N2.getOperand(1)) - return getSetCC(Cond, N1.getOperand(1), N2.getOperand(0)); + return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(0)); if (N1.getOperand(1) == N2.getOperand(0)) - return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1)); + return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(1)); } } // Simplify (X+Z) == X --> Z == 0 if (N1.getOperand(0) == N2) - return getSetCC(Cond, N1.getOperand(1), + return getSetCC(Cond, VT, N1.getOperand(1), getConstant(0, N1.getValueType())); if (N1.getOperand(1) == N2) { if (isCommutativeBinOp(N1.getOpcode())) - return getSetCC(Cond, N1.getOperand(0), + return getSetCC(Cond, VT, N1.getOperand(0), getConstant(0, N1.getValueType())); else { assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); // (Z-X) == X --> Z == X<<1 - return getSetCC(Cond, N1.getOperand(0), + return getSetCC(Cond, VT, N1.getOperand(0), getNode(ISD::SHL, N2.getValueType(), N2, getConstant(1, MVT::i8))); } @@ -455,10 +455,10 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1, N2.getOpcode() == ISD::XOR) { // Simplify X == (X+Z) --> Z == 0 if (N2.getOperand(0) == N1) - return getSetCC(Cond, N2.getOperand(1), + return getSetCC(Cond, VT, N2.getOperand(1), getConstant(0, N2.getValueType())); else if (N2.getOperand(1) == N1) - return getSetCC(Cond, N2.getOperand(0), + return getSetCC(Cond, VT, N2.getOperand(0), getConstant(0, N2.getValueType())); } } @@ -466,6 +466,7 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1, SetCCSDNode *&N = SetCCs[std::make_pair(std::make_pair(N1, N2), Cond)]; if (N) return SDOperand(N, 0); N = new SetCCSDNode(Cond, N1, N2); + N->setValueTypes(VT); AllNodes.push_back(N); return SDOperand(N, 0); } @@ -668,6 +669,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, // !(X op Y) -> (X !op Y) bool isInteger = MVT::isInteger(SetCC->getOperand(0).getValueType()); return getSetCC(ISD::getSetCCInverse(SetCC->getCondition(),isInteger), + SetCC->getValueType(0), SetCC->getOperand(0), SetCC->getOperand(1)); } else if (N1.getOpcode() == ISD::AND || N1.getOpcode() == ISD::OR) { SDNode *Op = N1.Val; @@ -746,7 +748,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, Result = ISD::getSetCCAndOperation(LHS->getCondition(), Op2, isInteger); if (Result != ISD::SETCC_INVALID) - return getSetCC(Result, LL, LR); + return getSetCC(Result, LHS->getValueType(0), LL, LR); } } break; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 87997ce7b52..09b5f3c010b 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -472,7 +472,7 @@ void SelectionDAGLowering::visitSetCC(User &I,ISD::CondCode SignedOpcode, ISD::CondCode Opcode = SignedOpcode; if (I.getOperand(0)->getType()->isUnsigned()) Opcode = UnsignedOpcode; - setValue(&I, DAG.getSetCC(Opcode, Op1, Op2)); + setValue(&I, DAG.getSetCC(Opcode, MVT::i1, Op1, Op2)); } void SelectionDAGLowering::visitSelect(User &I) { @@ -658,7 +658,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) { case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return; case Intrinsic::isunordered: - setValue(&I, DAG.getSetCC(ISD::SETUO, getValue(I.getOperand(1)), + setValue(&I, DAG.getSetCC(ISD::SETUO, MVT::i1, getValue(I.getOperand(1)), getValue(I.getOperand(2)))); return; }