Fixed DAGCombine optimizations which generate select_cc for targets
authorNadav Rotem <nadav.rotem@intel.com>
Mon, 23 Jul 2012 07:59:50 +0000 (07:59 +0000)
committerNadav Rotem <nadav.rotem@intel.com>
Mon, 23 Jul 2012 07:59:50 +0000 (07:59 +0000)
that do not support it (X86 does not lower select_cc).

PR: 13428

Together with Michael Kuperstein <michael.m.kuperstein@intel.com>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160619 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/X86/2012-07-23-select_cc.ll [new file with mode: 0644]

index 942db7d846528e9ac2f514a9c0d6cc1367f7e166..747bc446a718bf319f094411e730d3f0f68aa6ef 100644 (file)
@@ -6002,29 +6002,36 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) {
       return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), VT, N0);
   }
 
-  // fold (sint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
-  if (N0.getOpcode() == ISD::SETCC && N0.getValueType() == MVT::i1 &&
-      !VT.isVector() &&
-      (!LegalOperations ||
-       TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
-    SDValue Ops[] =
-      { N0.getOperand(0), N0.getOperand(1),
-        DAG.getConstantFP(-1.0, VT) , DAG.getConstantFP(0.0, VT),
-        N0.getOperand(2) };
-    return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
-  }
-
-  // fold (sint_to_fp (zext (setcc x, y, cc))) ->
-  //      (select_cc x, y, 1.0, 0.0,, cc)
-  if (N0.getOpcode() == ISD::ZERO_EXTEND &&
-      N0.getOperand(0).getOpcode() == ISD::SETCC &&!VT.isVector() &&
-      (!LegalOperations ||
-       TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
-    SDValue Ops[] =
-      { N0.getOperand(0).getOperand(0), N0.getOperand(0).getOperand(1),
-        DAG.getConstantFP(1.0, VT) , DAG.getConstantFP(0.0, VT),
-        N0.getOperand(0).getOperand(2) };
-    return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
+  // The next optimizations are desireable only if SELECT_CC can be lowered.
+  // Check against MVT::Other for SELECT_CC, which is a workaround for targets
+  // having to say they don't support SELECT_CC on every type the DAG knows
+  // about, since there is no way to mark an opcode illegal at all value types
+  // (See also visitSELECT)
+  if (TLI.isOperationLegalOrCustom(ISD::SELECT_CC, MVT::Other)) {
+    // fold (sint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
+    if (N0.getOpcode() == ISD::SETCC && N0.getValueType() == MVT::i1 &&
+        !VT.isVector() &&
+        (!LegalOperations ||
+         TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
+      SDValue Ops[] =
+        { N0.getOperand(0), N0.getOperand(1),
+          DAG.getConstantFP(-1.0, VT) , DAG.getConstantFP(0.0, VT),
+          N0.getOperand(2) };
+      return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
+    }
+
+    // fold (sint_to_fp (zext (setcc x, y, cc))) ->
+    //      (select_cc x, y, 1.0, 0.0,, cc)
+    if (N0.getOpcode() == ISD::ZERO_EXTEND &&
+        N0.getOperand(0).getOpcode() == ISD::SETCC &&!VT.isVector() &&
+        (!LegalOperations ||
+         TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
+      SDValue Ops[] =
+        { N0.getOperand(0).getOperand(0), N0.getOperand(0).getOperand(1),
+          DAG.getConstantFP(1.0, VT) , DAG.getConstantFP(0.0, VT),
+          N0.getOperand(0).getOperand(2) };
+      return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
+    }
   }
 
   return SDValue();
@@ -6052,17 +6059,24 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) {
       return DAG.getNode(ISD::SINT_TO_FP, N->getDebugLoc(), VT, N0);
   }
 
-  // fold (uint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
-  if (N0.getOpcode() == ISD::SETCC && !VT.isVector() &&
-      (!LegalOperations ||
-       TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
-    SDValue Ops[] =
-      { N0.getOperand(0), N0.getOperand(1),
-        DAG.getConstantFP(1.0, VT),  DAG.getConstantFP(0.0, VT),
-        N0.getOperand(2) };
-    return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
-  }
+  // The next optimizations are desireable only if SELECT_CC can be lowered.
+  // Check against MVT::Other for SELECT_CC, which is a workaround for targets
+  // having to say they don't support SELECT_CC on every type the DAG knows
+  // about, since there is no way to mark an opcode illegal at all value types
+  // (See also visitSELECT)
+  if (TLI.isOperationLegalOrCustom(ISD::SELECT_CC, MVT::Other)) {
+    // fold (uint_to_fp (setcc x, y, cc)) -> (select_cc x, y, -1.0, 0.0,, cc)
 
+    if (N0.getOpcode() == ISD::SETCC && !VT.isVector() &&
+        (!LegalOperations ||
+         TLI.isOperationLegalOrCustom(llvm::ISD::ConstantFP, VT))) {
+      SDValue Ops[] =
+        { N0.getOperand(0), N0.getOperand(1),
+          DAG.getConstantFP(1.0, VT),  DAG.getConstantFP(0.0, VT),
+          N0.getOperand(2) };
+      return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, Ops, 5);
+    }
+  }
 
   return SDValue();
 }
diff --git a/test/CodeGen/X86/2012-07-23-select_cc.ll b/test/CodeGen/X86/2012-07-23-select_cc.ll
new file mode 100644 (file)
index 0000000..33fcb12
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: llc < %s -march=x86-64 -mcpu=corei7
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; PR 13428
+
+declare void @use(double)
+
+define void @test() {
+entry:
+  call void @use(double 1.000000e+00)
+  %A = icmp eq i64 undef, 2
+  %B = zext i1 %A to i32
+  %C = sitofp i32 %B to double
+  call void @use(double %C)
+  call void @use(double 0.000000e+00)
+  unreachable
+}