[FuncSpec] Prevent assertion failure when no store value is found
authorJonathon Penix <jpenix@quicinc.com>
Tue, 7 Feb 2023 03:05:09 +0000 (19:05 -0800)
committerJonathon Penix <jpenix@quicinc.com>
Tue, 7 Feb 2023 21:57:27 +0000 (13:57 -0800)
If the only user of the Alloca argument provided to getPromotableAlloca()
is the same as the Call argument, StoreValue is never set and results
in an assertion failure that isa<> was used on a nullptr when passed into
getCandidateConstant().

This was originally seen when trying to build SPEC 2006 416.gamess using
flang with lto enabled.

Differential Revision: https://reviews.llvm.org/D143457

llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
llvm/test/Transforms/FunctionSpecialization/compiler-crash-promote-alloca.ll [new file with mode: 0644]

index 4a7efb2..51bc178 100644 (file)
@@ -125,6 +125,10 @@ Constant *FunctionSpecializer::getPromotableAlloca(AllocaInst *Alloca,
     // Bail if there is any other unknown usage.
     return nullptr;
   }
+
+  if (!StoreValue)
+    return nullptr;
+
   return getCandidateConstant(StoreValue);
 }
 
diff --git a/llvm/test/Transforms/FunctionSpecialization/compiler-crash-promote-alloca.ll b/llvm/test/Transforms/FunctionSpecialization/compiler-crash-promote-alloca.ll
new file mode 100644 (file)
index 0000000..3946b2d
--- /dev/null
@@ -0,0 +1,27 @@
+; RUN: opt -S --passes="ipsccp<func-spec>" -force-function-specialization < %s | FileCheck %s
+
+; Tests that `bar` has been specialized and that the compiler did not crash
+; while attempting to promote the alloca in `entry`.
+; CHECK: bar.1
+
+@block = internal global [8 x i8] zeroinitializer, align 1
+
+define dso_local void @entry() {
+  %1 = alloca i32, align 4
+  call void @foo(ptr nonnull %1)
+  ret void
+}
+
+define internal void @foo(ptr nocapture readnone %0) {
+  %2 = alloca i32, align 4
+  call void @bar(ptr nonnull %2, ptr nonnull @block)
+  call void @bar(ptr nonnull %2, ptr nonnull getelementptr inbounds ([8 x i8], ptr @block, i64 0, i64 4))
+  ret void
+}
+
+define internal void @bar(ptr nocapture readonly %0, ptr nocapture readonly %1) {
+  %3 = load i32, ptr %0, align 4
+  %4 = load i32, ptr %1, align 4
+  ret void
+}
+