From 87166905c8d58e152b06752f5d2f24a09ebbcbde Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Thu, 27 Aug 2015 21:46:04 +0000 Subject: [PATCH] [CodeGen] Check FoldConstantArithmetic result before using it. Fixes PR24602: r245689 introduced an unguarded use of SelectionDAG::FoldConstantArithmetic, which returns 0 when it fails because of opaque (hoisted) constants. llvm-svn: 246217 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 +++-- llvm/test/CodeGen/X86/pr24602.ll | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/X86/pr24602.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 3275daf3ffdd..693331fc19e4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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/llvm/test/CodeGen/X86/pr24602.ll b/llvm/test/CodeGen/X86/pr24602.ll new file mode 100644 index 000000000000..9c029aeefec9 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr24602.ll @@ -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 +}