[BasicAA] Fix assertion failure in alias() caused by non-pointer base in DecomposeGEPExpression (#191180)
When stripping a bitcast in DecomposeGEPExpression, the resulting
operand may have a non-scalar-pointer type (e.g. <1 x ptr>). Proceeding
with such a type as the decomposition base violates the AA assumption
that all pointers are scalar pointer types, triggering an assertion
failure on alias() call.
Add a type check in the bitcast/addrspacecast handling path to return
not stripped V as base when the stripped operand is not a scalar pointer
type.
Add a lit test verifying no crash on valid IR containing such a bitcast,
and checking that the alias query conservatively returns MayAlias.
Fixes #191157
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index dee305a6..d74075d 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -624,9 +624,11 @@
if (Op->getOpcode() == Instruction::BitCast ||
Op->getOpcode() == Instruction::AddrSpaceCast) {
Value *NewV = Op->getOperand(0);
- // Don't look through casts between address spaces with differing index
- // widths.
- if (DL.getIndexTypeSizeInBits(NewV->getType()) != IndexSize) {
+ auto *NewVTy = NewV->getType();
+ // Don't look through casts to non-scalar-pointer types or address spaces
+ // with differing index widths.
+ if (!isa<PointerType>(NewVTy) ||
+ DL.getIndexTypeSizeInBits(NewVTy) != IndexSize) {
Decomposed.Base = V;
return Decomposed;
}
diff --git a/llvm/test/Analysis/BasicAA/gep-decompose-bitcast-vector-type-mismatch.ll b/llvm/test/Analysis/BasicAA/gep-decompose-bitcast-vector-type-mismatch.ll
new file mode 100644
index 0000000..71eb333
--- /dev/null
+++ b/llvm/test/Analysis/BasicAA/gep-decompose-bitcast-vector-type-mismatch.ll
@@ -0,0 +1,14 @@
+; RUN: opt -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output < %s 2>&1 | FileCheck %s
+
+; Verify that BasicAA does not crash when DecomposeGEPExpression encounters
+; a bitcast whose stripped operand has a non-pointer type (e.g. <1 x ptr>).
+; The alias query should conservatively return MayAlias instead of hitting
+; an assertion in alias() which requires scalar pointer types.
+define void @test(ptr %C, i64 %0) {
+; CHECK-LABEL: test
+; CHECK: MayAlias: i32* %2, <2 x i16>* bitcast (<1 x ptr> <ptr inttoptr (i64 -1 to ptr)> to ptr)
+ %2 = getelementptr i8, ptr %C, i64 %0
+ store i32 0, ptr %2, align 4
+ store <2 x i16> zeroinitializer, ptr bitcast (<1 x ptr> <ptr inttoptr (i64 -1 to ptr)> to ptr), align 4
+ ret void
+}