[CodeGen] Check FoldConstantArithmetic result before using it.
authorAhmed Bougacha <ahmed.bougacha@gmail.com>
Thu, 27 Aug 2015 21:46:04 +0000 (21:46 +0000)
committerAhmed Bougacha <ahmed.bougacha@gmail.com>
Thu, 27 Aug 2015 21:46:04 +0000 (21:46 +0000)
Fixes PR24602: r245689 introduced an unguarded use of
SelectionDAG::FoldConstantArithmetic, which returns 0 when it fails
because of opaque (hoisted) constants.

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

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/X86/pr24602.ll [new file with mode: 0644]

index 3275daf3ffdd56b3de910d256a46748813c1cb08..693331fc19e45e13445a781154b31dacd105e57a 100644 (file)
@@ -4457,8 +4457,9 @@ SDValue DAGCombiner::visitSHL(SDNode *N) {
   // fold (shl (mul x, c1), c2) -> (mul x, c1 << c2)
   if (N1C && N0.getOpcode() == ISD::MUL && N0.getNode()->hasOneUse()) {
     if (ConstantSDNode *N0C1 = isConstOrConstSplat(N0.getOperand(1))) {
-      SDValue Folded = DAG.FoldConstantArithmetic(ISD::SHL, SDLoc(N1), VT, N0C1, N1C);
-      return DAG.getNode(ISD::MUL, SDLoc(N), VT, N0.getOperand(0), Folded);
+      if (SDValue Folded =
+              DAG.FoldConstantArithmetic(ISD::SHL, SDLoc(N1), VT, N0C1, N1C))
+        return DAG.getNode(ISD::MUL, SDLoc(N), VT, N0.getOperand(0), Folded);
     }
   }
 
diff --git a/test/CodeGen/X86/pr24602.ll b/test/CodeGen/X86/pr24602.ll
new file mode 100644 (file)
index 0000000..9c029ae
--- /dev/null
@@ -0,0 +1,17 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown  | FileCheck %s
+
+; PR24602: Make sure we don't barf on non-foldable code (with opaque constants).
+
+; CHECK-LABEL: pr24602:
+; CHECK-NEXT: # BB#0
+; CHECK-NEXT: movabsq $-10000000000, [[CST:%[a-z0-9]+]]
+; CHECK-NEXT: imulq [[CST]], %rsi
+; CHECK-NEXT: leaq (%rdi,%rsi,8), %rax
+; CHECK-NEXT: movq [[CST]], (%rdi,%rsi,8)
+; CHECK-NEXT: retq
+define i64* @pr24602(i64* %p, i64 %n) nounwind {
+  %mul = mul nsw i64 %n, -10000000000
+  %add.ptr = getelementptr inbounds i64, i64* %p, i64 %mul
+  store i64 -10000000000, i64* %add.ptr
+  ret i64* %add.ptr
+}