Fix a dagga combiner bug: avoid creating illegal constant.
authorEvan Cheng <evan.cheng@apple.com>
Tue, 21 Jul 2009 05:40:15 +0000 (05:40 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 21 Jul 2009 05:40:15 +0000 (05:40 +0000)
Is this really a winning transformation?
fold (shl (srl x, c1), c2) -> (shl (and x, (shl -1, c1)), (sub c2, c1)) or
                              (srl (and x, (shl -1, c1)), (sub c1, c2))

llvm-svn: 76535

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/X86/2009-07-20-DAGCombineBug.ll [new file with mode: 0644]

index 4ff2a3a..370054d 100644 (file)
@@ -2475,15 +2475,18 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
   if (N1C && N0.getOpcode() == ISD::SRL &&
       N0.getOperand(1).getOpcode() == ISD::Constant) {
     uint64_t c1 = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
-    uint64_t c2 = N1C->getZExtValue();
-    SDValue Mask = DAG.getNode(ISD::AND, N0.getDebugLoc(), VT, N0.getOperand(0),
-                               DAG.getConstant(~0ULL << c1, VT));
-    if (c2 > c1)
-      return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, Mask,
-                         DAG.getConstant(c2-c1, N1.getValueType()));
-    else
-      return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, Mask,
-                         DAG.getConstant(c1-c2, N1.getValueType()));
+    if (c1 < VT.getSizeInBits()) {
+      uint64_t c2 = N1C->getZExtValue();
+      SDValue Mask = DAG.getNode(ISD::AND, N0.getDebugLoc(), VT,
+                                 N0.getOperand(0),
+                                 DAG.getConstant(~0ULL << c1, VT));
+      if (c2 > c1)
+        return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, Mask,
+                           DAG.getConstant(c2-c1, N1.getValueType()));
+      else
+        return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, Mask,
+                           DAG.getConstant(c1-c2, N1.getValueType()));
+    }
   }
   // fold (shl (sra x, c1), c1) -> (and x, (shl -1, c1))
   if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1))
diff --git a/llvm/test/CodeGen/X86/2009-07-20-DAGCombineBug.ll b/llvm/test/CodeGen/X86/2009-07-20-DAGCombineBug.ll
new file mode 100644 (file)
index 0000000..51aa88d
--- /dev/null
@@ -0,0 +1,29 @@
+; RUN: llvm-as < %s | llc -march=x86
+
+@bsBuff = internal global i32 0                ; <i32*> [#uses=1]
+@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @bsGetUInt32 to i8*)], section "llvm.metadata"           ; <[1 x i8*]*> [#uses=0]
+
+define fastcc i32 @bsGetUInt32() nounwind ssp {
+entry:
+       %bsBuff.promoted44 = load i32* @bsBuff          ; <i32> [#uses=1]
+       %0 = add i32 0, -8              ; <i32> [#uses=1]
+       %1 = lshr i32 %bsBuff.promoted44, %0            ; <i32> [#uses=1]
+       %2 = shl i32 %1, 8              ; <i32> [#uses=1]
+       br label %bb3.i17
+
+bb3.i9:                ; preds = %bb3.i17
+       br i1 false, label %bb2.i16, label %bb1.i15
+
+bb1.i15:               ; preds = %bb3.i9
+       unreachable
+
+bb2.i16:               ; preds = %bb3.i9
+       br label %bb3.i17
+
+bb3.i17:               ; preds = %bb2.i16, %entry
+       br i1 false, label %bb3.i9, label %bsR.exit18
+
+bsR.exit18:            ; preds = %bb3.i17
+       %3 = or i32 0, %2               ; <i32> [#uses=0]
+       ret i32 0
+}