Fix PR3763 by using proper APInt methods instead of uint64_t's.
authorChris Lattner <sabre@nondot.org>
Mon, 9 Mar 2009 20:22:18 +0000 (20:22 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 9 Mar 2009 20:22:18 +0000 (20:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66434 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/X86/2009-03-09-APIntCrash.ll [new file with mode: 0644]

index 407814ce133e1a951b7118c046da1a265ac287d7..b4e8592c81f2f4eda4a46fe36f197c7c4ded4504 100644 (file)
@@ -1311,14 +1311,15 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
                        DAG.getConstant(N1C->getAPIntValue().logBase2(),
                                        getShiftAmountTy()));
   // fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c
-  if (N1C && isPowerOf2_64(-N1C->getSExtValue()))
+  if (N1C && (-N1C->getAPIntValue()).isPowerOf2()) {
+    unsigned Log2Val = (-N1C->getAPIntValue()).logBase2();
     // FIXME: If the input is something that is easily negated (e.g. a
     // single-use add), we should put the negate there.
     return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
                        DAG.getConstant(0, VT),
                        DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0,
-                            DAG.getConstant(Log2_64(-N1C->getSExtValue()),
-                                            getShiftAmountTy())));
+                            DAG.getConstant(Log2Val, getShiftAmountTy())));
+  }
   // (mul (shl X, c1), c2) -> (mul X, c2 << c1)
   if (N1C && N0.getOpcode() == ISD::SHL &&
       isa<ConstantSDNode>(N0.getOperand(1))) {
diff --git a/test/CodeGen/X86/2009-03-09-APIntCrash.ll b/test/CodeGen/X86/2009-03-09-APIntCrash.ll
new file mode 100644 (file)
index 0000000..d7b5269
--- /dev/null
@@ -0,0 +1,25 @@
+; RUN: llvm-as < %s | llc -march=x86-64
+; PR3763
+       %struct.__block_descriptor = type { i64, i64 }
+
+define %struct.__block_descriptor @evUTCTime() nounwind {
+entry:
+       br i1 false, label %if.then, label %return
+
+if.then:               ; preds = %entry
+       %srcval18 = load i128* null, align 8            ; <i128> [#uses=1]
+       %tmp15 = lshr i128 %srcval18, 64                ; <i128> [#uses=1]
+       %tmp9 = mul i128 %tmp15, 18446744073709551616000                ; <i128> [#uses=1]
+       br label %return
+
+return:                ; preds = %if.then, %entry
+       %retval.0 = phi i128 [ %tmp9, %if.then ], [ undef, %entry ]             ; <i128> [#uses=0]
+       ret %struct.__block_descriptor undef
+}
+
+define i128 @test(i128 %arg) nounwind {
+       %A = shl i128 1, 92
+       %B = sub i128 0, %A
+       %C = mul i128 %arg, %B
+       ret i128 %C  ;; should codegen to neg(shift)
+}