[CGP] r205941 changed the logic, so that a cast happens *before* 'Result' is
authorJoey Gouly <joey.gouly@gmail.com>
Tue, 13 May 2014 15:42:45 +0000 (15:42 +0000)
committerJoey Gouly <joey.gouly@gmail.com>
Tue, 13 May 2014 15:42:45 +0000 (15:42 +0000)
compared to 'AddrMode.BaseReg'. In the case that 'AddrMode.BaseReg' is
nullptr, 'Result' will also be nullptr, so the cast causes an assertion. We
should use dyn_cast_or_null here to check 'Result' is not null and it is an
instruction.

Bug found by Mats Petersson, and I reduced his IR to get a test case.

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

lib/CodeGen/CodeGenPrepare.cpp
test/CodeGen/X86/codegen-prepare-crash.ll [new file with mode: 0644]

index d2559cf53d2306adb4d42937f6f2ae09dae42d36..a6d8a68588d0540d8902b17fa1bca1db03212cf1 100644 (file)
@@ -2759,7 +2759,7 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
         // the original IR value was tossed in favor of a constant back when
         // the AddrMode was created we need to bail out gracefully if widths
         // do not match instead of extending it.
         // the original IR value was tossed in favor of a constant back when
         // the AddrMode was created we need to bail out gracefully if widths
         // do not match instead of extending it.
-        Instruction *I = dyn_cast<Instruction>(Result);
+        Instruction *I = dyn_cast_or_null<Instruction>(Result);
         if (I && (Result != AddrMode.BaseReg))
           I->eraseFromParent();
         return false;
         if (I && (Result != AddrMode.BaseReg))
           I->eraseFromParent();
         return false;
diff --git a/test/CodeGen/X86/codegen-prepare-crash.ll b/test/CodeGen/X86/codegen-prepare-crash.ll
new file mode 100644 (file)
index 0000000..c328817
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: llc < %s
+target triple = "x86_64-unknown-linux-gnu"
+
+@g = external global [10 x i32]
+
+define void @f(i32 %u) {
+  %1 = add i32 %u, 4
+  br label %P.Proc8.exit
+
+P.Proc8.exit:
+  %valueindex35.i = getelementptr [10 x i32]* @g, i32 0, i32 %1
+  store i32 %u, i32* %valueindex35.i
+  ret void
+}