diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp --- a/llvm/lib/Analysis/MemorySSA.cpp +++ b/llvm/lib/Analysis/MemorySSA.cpp @@ -1758,10 +1758,10 @@ bool DefCheck, UseCheck; DefCheck = isModSet(ModRef) || isOrdered(I); UseCheck = isRefSet(ModRef); - // Use set is not checked since AA may return better results as a result of - // other transforms. - // FIXME: Would Def value always be consistent after transforms? - assert(Def == DefCheck && "Invalid template"); + // Memory accesses should only be reduced and can not be increased since AA + // just might return better results as a result of some transformations. + assert((Def == DefCheck || !DefCheck) && + "Memory accesses should only be reduced"); if (!Def && Use != UseCheck) { // New Access should not have more power than template access assert(!UseCheck && "Invalid template"); diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/pr59546.ll b/llvm/test/Transforms/SimpleLoopUnswitch/pr59546.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/SimpleLoopUnswitch/pr59546.ll @@ -0,0 +1,41 @@ +; RUN: opt -passes="scc-oz-module-inliner,function(loop-mssa(no-op-loop)),recompute-globalsaa,function(loop-mssa(simple-loop-unswitch))" -disable-output < %s +; Check that don't crash if the Alias Analysis returns better results than +; before when cloning loop's memoryssa. + +@a = internal global i16 0 + +define void @h() { +entry: + br label %end + +body: ; No predecessors! + call void @g(ptr null) + br label %end + +end: ; preds = %while.body, %entry + ret void +} + +define internal void @g(ptr %a) #0 { +entry: + br label %while.cond + +while.cond: ; preds = %while.body, %entry + %0 = load i16, ptr %a, align 1 + %tobool.not = icmp eq i16 %0, 0 + br i1 %tobool.not, label %while.end, label %while.body + +while.body: ; preds = %while.cond + call void @f() + br label %while.cond + +while.end: ; preds = %while.cond + ret void +} + +define internal void @f() #0 { + store i16 0, ptr @a, align 1 + ret void +} + +attributes #0 = { noinline }