[llvm-commits] [llvm] r57542 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/setoeq.ll
Evan Cheng
evan.cheng at apple.com
Tue Oct 14 19:05:33 PDT 2008
Author: evancheng
Date: Tue Oct 14 21:05:31 2008
New Revision: 57542
URL: http://llvm.org/viewvc/llvm-project?rev=57542&view=rev
Log:
- Add target lowering hooks that specify which setcc conditions are illegal,
i.e. conditions that cannot be checked with a single instruction. For example,
SETONE and SETUEQ on x86.
- Teach legalizer to implement *illegal* setcc as a and / or of a number of
legal setcc nodes. For now, only implement FP conditions. e.g. SETONE is
implemented as SETO & SETNE, SETUEQ is SETUO | SETEQ.
- Move x86 target over.
Added:
llvm/trunk/test/CodeGen/X86/setoeq.ll
Modified:
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=57542&r1=57541&r2=57542&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Tue Oct 14 21:05:31 2008
@@ -409,6 +409,28 @@
getConvertAction(FromVT, ToVT) == Custom);
}
+ /// getCondCodeAction - Return how the condition code should be treated:
+ /// either it is legal, needs to be expanded to some other code sequence,
+ /// or the target has a custom expander for it.
+ LegalizeAction
+ getCondCodeAction(ISD::CondCode CC, MVT VT) const {
+ assert((unsigned)CC < array_lengthof(CondCodeActions) &&
+ (unsigned)VT.getSimpleVT() < sizeof(CondCodeActions[0])*4 &&
+ "Table isn't big enough!");
+ LegalizeAction Action = (LegalizeAction)
+ ((CondCodeActions[CC] >> (2*VT.getSimpleVT())) & 3);
+ assert(Action != Promote && "Can't promote condition code!");
+ return Action;
+ }
+
+ /// isCondCodeLegal - Return true if the specified condition code is legal
+ /// on this target.
+ bool isCondCodeLegal(ISD::CondCode CC, MVT VT) const {
+ return getCondCodeAction(CC, VT) == Legal ||
+ getCondCodeAction(CC, VT) == Custom;
+ }
+
+
/// getTypeToPromoteTo - If the action for this operation is to promote, this
/// method returns the ValueType to promote to.
MVT getTypeToPromoteTo(unsigned Op, MVT VT) const {
@@ -903,6 +925,16 @@
ToVT.getSimpleVT()*2;
}
+ /// setCondCodeAction - Indicate that the specified condition code is or isn't
+ /// supported on the target and indicate what to do about it.
+ void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action) {
+ assert((unsigned)VT.getSimpleVT() < sizeof(CondCodeActions[0])*4 &&
+ (unsigned)CC < array_lengthof(CondCodeActions) &&
+ "Table isn't big enough!");
+ CondCodeActions[(unsigned)CC] &= ~(uint64_t(3UL) << VT.getSimpleVT()*2);
+ CondCodeActions[(unsigned)CC] |= (uint64_t)Action << VT.getSimpleVT()*2;
+ }
+
/// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
/// promotion code defaults to trying a larger integer/fp until it can find
/// one that works. If that default is insufficient, this method can be used
@@ -1437,6 +1469,11 @@
/// (FP_EXTEND and FP_ROUND).
uint64_t ConvertActions[MVT::LAST_VALUETYPE];
+ /// CondCodeActions - For each condition code (ISD::CondCode) keep a
+ /// LegalizeAction that indicates how instruction selection should
+ /// deal with the condition code.
+ uint64_t CondCodeActions[ISD::SETCC_INVALID];
+
ValueTypeActionImpl ValueTypeActions;
std::vector<APFloat> LegalFPImmediates;
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=57542&r1=57541&r2=57542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Oct 14 21:05:31 2008
@@ -193,6 +193,11 @@
SmallPtrSet<SDNode*, 32> &NodesLeadingTo);
void LegalizeSetCCOperands(SDValue &LHS, SDValue &RHS, SDValue &CC);
+ void LegalizeSetCCCondCode(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC);
+ void LegalizeSetCC(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC) {
+ LegalizeSetCCOperands(LHS, RHS, CC);
+ LegalizeSetCCCondCode(VT, LHS, RHS, CC);
+ }
SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned,
SDValue &Hi);
@@ -1886,10 +1891,10 @@
Tmp3 = Node->getOperand(3); // RHS
Tmp4 = Node->getOperand(1); // CC
- LegalizeSetCCOperands(Tmp2, Tmp3, Tmp4);
+ LegalizeSetCC(Node->getValueType(0), Tmp2, Tmp3, Tmp4);
LastCALLSEQ_END = DAG.getEntryNode();
- // If we didn't get both a LHS and RHS back from LegalizeSetCCOperands,
+ // If we didn't get both a LHS and RHS back from LegalizeSetCC,
// the LHS is a legal SETCC itself. In this case, we need to compare
// the result against zero to select between true and false values.
if (Tmp3.getNode() == 0) {
@@ -2772,9 +2777,9 @@
Tmp4 = LegalizeOp(Node->getOperand(3)); // False
SDValue CC = Node->getOperand(4);
- LegalizeSetCCOperands(Tmp1, Tmp2, CC);
+ LegalizeSetCC(Node->getValueType(0), Tmp1, Tmp2, CC);
- // If we didn't get both a LHS and RHS back from LegalizeSetCCOperands,
+ // If we didn't get both a LHS and RHS back from LegalizeSetCC,
// the LHS is a legal SETCC itself. In this case, we need to compare
// the result against zero to select between true and false values.
if (Tmp2.getNode() == 0) {
@@ -2798,7 +2803,7 @@
Tmp1 = Node->getOperand(0);
Tmp2 = Node->getOperand(1);
Tmp3 = Node->getOperand(2);
- LegalizeSetCCOperands(Tmp1, Tmp2, Tmp3);
+ LegalizeSetCC(Node->getValueType(0), Tmp1, Tmp2, Tmp3);
// If we had to Expand the SetCC operands into a SELECT node, then it may
// not always be possible to return a true LHS & RHS. In this case, just
@@ -4877,6 +4882,50 @@
RHS = Tmp2;
}
+/// LegalizeSetCCCondCode - Legalize a SETCC with given LHS and RHS and
+/// condition code CC on the current target. This routine assumes LHS and rHS
+/// have already been legalized by LegalizeSetCCOperands. It expands SETCC with
+/// illegal condition code into AND / OR of multiple SETCC values.
+void SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT,
+ SDValue &LHS, SDValue &RHS,
+ SDValue &CC) {
+ MVT OpVT = LHS.getValueType();
+ ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
+ switch (TLI.getCondCodeAction(CCCode, OpVT)) {
+ default: assert(0 && "Unknown condition code action!");
+ case TargetLowering::Legal:
+ // Nothing to do.
+ break;
+ case TargetLowering::Expand: {
+ ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID;
+ unsigned Opc = 0;
+ switch (CCCode) {
+ default: assert(0 && "Don't know how to expand this condition!"); abort();
+ case ISD::SETOEQ: CC1 = ISD::SETO; CC2 = ISD::SETEQ; Opc = ISD::AND; break;
+ case ISD::SETOGT: CC1 = ISD::SETO; CC2 = ISD::SETGT; Opc = ISD::AND; break;
+ case ISD::SETOGE: CC1 = ISD::SETO; CC2 = ISD::SETGE; Opc = ISD::AND; break;
+ case ISD::SETOLT: CC1 = ISD::SETO; CC2 = ISD::SETLT; Opc = ISD::AND; break;
+ case ISD::SETOLE: CC1 = ISD::SETO; CC2 = ISD::SETLE; Opc = ISD::AND; break;
+ case ISD::SETONE: CC1 = ISD::SETO; CC2 = ISD::SETNE; Opc = ISD::AND; break;
+ case ISD::SETUEQ: CC1 = ISD::SETUO; CC2 = ISD::SETEQ; Opc = ISD::OR; break;
+ case ISD::SETUGT: CC1 = ISD::SETUO; CC2 = ISD::SETGT; Opc = ISD::OR; break;
+ case ISD::SETUGE: CC1 = ISD::SETUO; CC2 = ISD::SETGE; Opc = ISD::OR; break;
+ case ISD::SETULT: CC1 = ISD::SETUO; CC2 = ISD::SETLT; Opc = ISD::OR; break;
+ case ISD::SETULE: CC1 = ISD::SETUO; CC2 = ISD::SETLE; Opc = ISD::OR; break;
+ case ISD::SETUNE: CC1 = ISD::SETUO; CC2 = ISD::SETNE; Opc = ISD::OR; break;
+ // FIXME: Implement more expansions.
+ }
+
+ SDValue SetCC1 = DAG.getSetCC(VT, LHS, RHS, CC1);
+ SDValue SetCC2 = DAG.getSetCC(VT, LHS, RHS, CC2);
+ LHS = DAG.getNode(Opc, VT, SetCC1, SetCC2);
+ RHS = SDValue();
+ CC = SDValue();
+ break;
+ }
+ }
+}
+
/// EmitStackConvert - Emit a store/load combination to the stack. This stores
/// SrcOp to a stack slot of type SlotVT, truncating it if needed. It then does
/// a load from the stack slot to DestVT, extending it if needed.
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=57542&r1=57541&r2=57542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Tue Oct 14 21:05:31 2008
@@ -406,6 +406,7 @@
memset(TruncStoreActions, 0, sizeof(TruncStoreActions));
memset(IndexedModeActions, 0, sizeof(IndexedModeActions));
memset(ConvertActions, 0, sizeof(ConvertActions));
+ memset(CondCodeActions, 0, sizeof(CondCodeActions));
// Set default actions for various operations.
for (unsigned VT = 0; VT != (unsigned)MVT::LAST_VALUETYPE; ++VT) {
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=57542&r1=57541&r2=57542&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Oct 14 21:05:31 2008
@@ -92,7 +92,15 @@
setTruncStoreAction(MVT::i64, MVT::i8 , Expand);
setTruncStoreAction(MVT::i32, MVT::i16, Expand);
setTruncStoreAction(MVT::i32, MVT::i8 , Expand);
- setTruncStoreAction(MVT::i16, MVT::i8, Expand);
+ setTruncStoreAction(MVT::i16, MVT::i8, Expand);
+
+ // SETOEQ and SETUNE require checking two conditions.
+ setCondCodeAction(ISD::SETOEQ, MVT::f32, Expand);
+ setCondCodeAction(ISD::SETOEQ, MVT::f64, Expand);
+ setCondCodeAction(ISD::SETOEQ, MVT::f80, Expand);
+ setCondCodeAction(ISD::SETUNE, MVT::f32, Expand);
+ setCondCodeAction(ISD::SETUNE, MVT::f64, Expand);
+ setCondCodeAction(ISD::SETUNE, MVT::f80, Expand);
// Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
// operation.
@@ -4883,26 +4891,8 @@
DAG.getConstant(X86CC, MVT::i8), Cond);
}
- assert(isFP && "Illegal integer SetCC!");
-
- Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Op0, Op1);
- switch (SetCCOpcode) {
- default: assert(false && "Illegal floating point SetCC!");
- case ISD::SETOEQ: { // !PF & ZF
- SDValue Tmp1 = DAG.getNode(X86ISD::SETCC, MVT::i8,
- DAG.getConstant(X86::COND_NP, MVT::i8), Cond);
- SDValue Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
- DAG.getConstant(X86::COND_E, MVT::i8), Cond);
- return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2);
- }
- case ISD::SETUNE: { // PF | !ZF
- SDValue Tmp1 = DAG.getNode(X86ISD::SETCC, MVT::i8,
- DAG.getConstant(X86::COND_P, MVT::i8), Cond);
- SDValue Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8,
- DAG.getConstant(X86::COND_NE, MVT::i8), Cond);
- return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2);
- }
- }
+ assert(0 && "Illegal SetCC!");
+ return SDValue();
}
SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) {
Added: llvm/trunk/test/CodeGen/X86/setoeq.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/setoeq.ll?rev=57542&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/setoeq.ll (added)
+++ llvm/trunk/test/CodeGen/X86/setoeq.ll Tue Oct 14 21:05:31 2008
@@ -0,0 +1,11 @@
+; RUN: llvm-as < %s | llc -march=x86 | grep set | count 2
+; RUN: llvm-as < %s | llc -march=x86 | grep and
+
+define zeroext i8 @t(double %x) nounwind readnone {
+entry:
+ %0 = fptosi double %x to i32 ; <i32> [#uses=1]
+ %1 = sitofp i32 %0 to double ; <double> [#uses=1]
+ %2 = fcmp oeq double %1, %x ; <i1> [#uses=1]
+ %retval12 = zext i1 %2 to i8 ; <i8> [#uses=1]
+ ret i8 %retval12
+}
More information about the llvm-commits
mailing list