Skip to content

Commit d432263

Browse files
authored
[LAA] Fix type mismatch in getStartAndEndForAccess. (llvm#183116)
`SE.getUMaxExpr` causes assertion failure due to type mismatch here: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Analysis/LoopAccessAnalysis.cpp#L253 Running `opt -S -p loop-vectorize -debug-only=loop-vectorize llvm/test/Analysis/LoopAccessAnalysis/type-mismatch-in-scalar-evolution.ll ` without the changes made in LoopAccessAnalysis.cpp causes assertion failure. Attaching the stack dump for reference: ``` LV: Checking a loop in 'loop_contains_store_assumed_bounds' from input.ll LV: Loop hints: force=? width=4 interleave=0 LV: Found a loop: for.body LV: Found an induction variable. opt: /home/kshitij/llvm-project/llvm/lib/Analysis/ScalarEvolution.cpp:3918: const llvm::SCEV* llvm::ScalarEvolution::getMinMaxExpr(llvm::SCEVTypes, llvm::SmallVectorImpl<const llvm::SCEV*>&): Assertion `getEffectiveSCEVType(Ops[i]->getType()) == ETy && "Operand types don't match!"' failed. PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug. Stack dump: 0. Program arguments: opt -S -passes=loop-vectorize -debug-only=loop-vectorize -force-vector-width=4 -disable-output input.ll 1. Running pass "function(loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>)" on module "input.ll" 2. Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "loop_contains_store_assumed_bounds" #0 0x000058ee97c5e652 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/local/bin/opt+0x4f44652) #1 0x000058ee97c5af0f llvm::sys::RunSignalHandlers() (/usr/local/bin/opt+0x4f40f0f) #2 0x000058ee97c5b05c SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0 llvm#3 0x00007c49d4c45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330) llvm#4 0x00007c49d4c9eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76 llvm#5 0x00007c49d4c9eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10 llvm#6 0x00007c49d4c9eb2c pthread_kill ./nptl/pthread_kill.c:89:10 llvm#7 0x00007c49d4c4527e raise ./signal/../sysdeps/posix/raise.c:27:6 llvm#8 0x00007c49d4c288ff abort ./stdlib/abort.c:81:7 llvm#9 0x00007c49d4c2881b _nl_load_domain ./intl/loadmsgcat.c:1177:9 llvm#10 0x00007c49d4c3b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517) llvm#11 0x000058ee98003fdb llvm::ScalarEvolution::getMinMaxExpr(llvm::SCEVTypes, llvm::SmallVectorImpl<llvm::SCEV const*>&) (/usr/local/bin/opt+0x52e9fdb) llvm#12 0x000058ee98004507 llvm::ScalarEvolution::getUMaxExpr(llvm::SCEV const*, llvm::SCEV const*) (/usr/local/bin/opt+0x52ea507) llvm#13 0x000058ee980dc728 llvm::getStartAndEndForAccess(llvm::Loop const*, llvm::SCEV const*, llvm::Type*, llvm::SCEV const*, llvm::SCEV const*, llvm::ScalarEvolution*, llvm::DenseMap<std::pair<llvm::SCEV const*, llvm::Type*>, std::pair<llvm::SCEV const*, llvm::SCEV const*>, llvm::DenseMapInfo<std::pair<llvm::SCEV const*, llvm::Type*>, void>, llvm::detail::DenseMapPair<std::pair<llvm::SCEV const*, llvm::Type*>, std::pair<llvm::SCEV const*, llvm::SCEV const*>>>*, llvm::DominatorTree*, llvm::AssumptionCache*, std::optional<llvm::ScalarEvolution::LoopGuards>&) (/usr/local/bin/opt+0x53c2728) llvm#14 0x000058ee9814008b llvm::isDereferenceableAndAlignedInLoop(llvm::LoadInst*, llvm::Loop*, llvm::ScalarEvolution&, llvm::DominatorTree&, llvm::AssumptionCache*, llvm::SmallVectorImpl<llvm::SCEVPredicate const*>*) (/usr/local/bin/opt+0x542608b) llvm#15 0x000058ee9a0fa1ca llvm::LoopVectorizationLegality::canUncountableExitConditionLoadBeMoved(llvm::BasicBlock*) (/usr/local/bin/opt+0x73e01ca) llvm#16 0x000058ee9a0faee0 llvm::LoopVectorizationLegality::isVectorizableEarlyExitLoop() (/usr/local/bin/opt+0x73e0ee0) llvm#17 0x000058ee9a104678 llvm::LoopVectorizationLegality::canVectorize(bool) (/usr/local/bin/opt+0x73ea678) llvm#18 0x000058ee9a08c953 llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/usr/local/bin/opt+0x7372953) llvm#19 0x000058ee9a090e21 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/usr/local/bin/opt+0x7376e21) llvm#20 0x000058ee9a0914e0 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/usr/local/bin/opt+0x73774e0) llvm#21 0x000058ee99e419a5 llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) PassBuilderPipelines.cpp:0:0 llvm#22 0x000058ee97f18905 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/usr/local/bin/opt+0x51fe905) llvm#23 0x000058ee995d70d5 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) AMDGPUTargetMachine.cpp:0:0 llvm#24 0x000058ee97f17051 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/usr/local/bin/opt+0x51fd051) llvm#25 0x000058ee995d7775 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) AMDGPUTargetMachine.cpp:0:0 llvm#26 0x000058ee97f1783d llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/usr/local/bin/opt+0x51fd83d) llvm#27 0x000058ee9c153909 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool, bool) (/usr/local/bin/opt+0x9439909) llvm#28 0x000058ee97c3f380 optMain (/usr/local/bin/opt+0x4f25380) llvm#29 0x00007c49d4c2a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3 llvm#30 0x00007c49d4c2a28b call_init ./csu/../csu/libc-start.c:128:20 llvm#31 0x00007c49d4c2a28b __libc_start_main ./csu/../csu/libc-start.c:347:5 llvm#32 0x000058ee97c309a5 _start (/usr/local/bin/opt+0x4f169a5) ``` This is caused by a type mismatch between `SE.getSCEV(DerefRK.IRArgValue)` and `DerefBytesSCEV`. Fixing this by extending them to the wider type.
1 parent 78a4b8e commit d432263

2 files changed

Lines changed: 59 additions & 2 deletions

File tree

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,12 @@ static bool evaluatePtrAddRecAtMaxBTCWillNotWrap(
250250
return true;
251251
});
252252
if (DerefRK) {
253-
DerefBytesSCEV =
254-
SE.getUMaxExpr(DerefBytesSCEV, SE.getSCEV(DerefRK.IRArgValue));
253+
const SCEV *DerefRKSCEV = SE.getSCEV(DerefRK.IRArgValue);
254+
Type *CommonTy =
255+
SE.getWiderType(DerefBytesSCEV->getType(), DerefRKSCEV->getType());
256+
DerefBytesSCEV = SE.getNoopOrZeroExtend(DerefBytesSCEV, CommonTy);
257+
DerefRKSCEV = SE.getNoopOrZeroExtend(DerefRKSCEV, CommonTy);
258+
DerefBytesSCEV = SE.getUMaxExpr(DerefBytesSCEV, DerefRKSCEV);
255259
}
256260

257261
if (DerefBytesSCEV->isZero())

llvm/test/Transforms/LoopVectorize/dereferenceable-info-from-assumption-variable-size.ll

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,3 +759,56 @@ loop.latch: ; preds = %loop.then, %loop
759759
exit:
760760
ret void
761761
}
762+
763+
; Test to check type mismatch while calling getUMaxExpr()
764+
; Function Attrs: mustprogress norecurse nosync nounwind ssp memory(read, inaccessiblemem: write, target_mem0: none, target_mem1: none) uwtable(sync)
765+
define void @test_assumed_bounds_type_mismatch(ptr noalias %array, ptr readonly %pred, i32 %n) nosync nofree {
766+
; CHECK-LABEL: define void @test_assumed_bounds_type_mismatch(
767+
; CHECK-SAME: ptr noalias [[ARRAY:%.*]], ptr readonly [[PRED:%.*]], i32 [[N:%.*]]) #[[ATTR1]] {
768+
; CHECK-NEXT: [[ENTRY:.*]]:
769+
; CHECK-NEXT: [[N_BYTES:%.*]] = mul nuw nsw i32 [[N]], 2
770+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PRED]], i32 [[N_BYTES]]) ]
771+
; CHECK-NEXT: [[TC:%.*]] = sext i32 [[N]] to i64
772+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
773+
; CHECK: [[FOR_BODY]]:
774+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[FOR_INC:.*]] ]
775+
; CHECK-NEXT: [[ST_ADDR:%.*]] = getelementptr inbounds i16, ptr [[ARRAY]], i64 [[IV]]
776+
; CHECK-NEXT: [[DATA:%.*]] = load i16, ptr [[ST_ADDR]], align 2
777+
; CHECK-NEXT: [[INC:%.*]] = add nsw i16 [[DATA]], 1
778+
; CHECK-NEXT: store i16 [[INC]], ptr [[ST_ADDR]], align 2
779+
; CHECK-NEXT: [[EE_ADDR:%.*]] = getelementptr inbounds i16, ptr [[PRED]], i64 [[IV]]
780+
; CHECK-NEXT: [[EE_VAL:%.*]] = load i16, ptr [[EE_ADDR]], align 2
781+
; CHECK-NEXT: [[EE_COND:%.*]] = icmp sgt i16 [[EE_VAL]], 500
782+
; CHECK-NEXT: br i1 [[EE_COND]], label %[[EXIT:.*]], label %[[FOR_INC]]
783+
; CHECK: [[FOR_INC]]:
784+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
785+
; CHECK-NEXT: [[COUNTED_COND:%.*]] = icmp eq i64 [[IV_NEXT]], [[TC]]
786+
; CHECK-NEXT: br i1 [[COUNTED_COND]], label %[[EXIT]], label %[[FOR_BODY]]
787+
; CHECK: [[EXIT]]:
788+
; CHECK-NEXT: ret void
789+
;
790+
entry:
791+
%n_bytes = mul nuw nsw i32 %n, 2
792+
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %pred, i32 %n_bytes) ]
793+
%tc = sext i32 %n to i64
794+
br label %for.body
795+
796+
for.body:
797+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
798+
%st.addr = getelementptr inbounds i16, ptr %array, i64 %iv
799+
%data = load i16, ptr %st.addr, align 2
800+
%inc = add nsw i16 %data, 1
801+
store i16 %inc, ptr %st.addr, align 2
802+
%ee.addr = getelementptr inbounds i16, ptr %pred, i64 %iv
803+
%ee.val = load i16, ptr %ee.addr, align 2
804+
%ee.cond = icmp sgt i16 %ee.val, 500
805+
br i1 %ee.cond, label %exit, label %for.inc
806+
807+
for.inc:
808+
%iv.next = add nuw nsw i64 %iv, 1
809+
%counted.cond = icmp eq i64 %iv.next, %tc
810+
br i1 %counted.cond, label %exit, label %for.body
811+
812+
exit:
813+
ret void
814+
}

0 commit comments

Comments
 (0)