Index: lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- lib/Transforms/Utils/SimplifyCFG.cpp +++ lib/Transforms/Utils/SimplifyCFG.cpp @@ -4189,6 +4189,7 @@ Builder.CreateAssumption(Builder.CreateNot(Cond)); Builder.CreateBr(BI->getSuccessor(1)); EraseTerminatorAndDCECond(BI); + Changed = true; } else if (BI->getSuccessor(1) == BB) { Builder.CreateAssumption(Cond); Builder.CreateBr(BI->getSuccessor(0)); Index: test/Transforms/SimplifyCFG/invalidate-dom.ll =================================================================== --- /dev/null +++ test/Transforms/SimplifyCFG/invalidate-dom.ll @@ -0,0 +1,90 @@ +; RUN: opt -aa-pipeline=default -passes="default" -disable-output %s +; REQUIRES: asserts +; PR42272 + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@b = external global i32, align 4 +@f = external global i32, align 4 +@g = external global i32, align 4 + +define i32* @a(i32 %h) #0 { +entry: + %h.addr = alloca i32, align 4 + store i32 %h, i32* %h.addr, align 4 + %0 = load i32, i32* %h.addr, align 4 + switch i32 %0, label %sw.default [ + i32 4, label %sw.bb + i32 3, label %sw.bb1 + i32 2, label %sw.bb3 + ] + +sw.bb: ; preds = %entry + %call = call i32 (...) @c() + unreachable + +sw.bb1: ; preds = %entry + %call2 = call i32 (...) @c() + unreachable + +sw.bb3: ; preds = %entry + %call4 = call i32 (...) @c() + %conv = sext i32 %call4 to i64 + %1 = inttoptr i64 %conv to i32* + ret i32* %1 + +sw.default: ; preds = %entry + unreachable +} + +define i32 @m() #1 { +entry: + %call = call i32 @j() + %call1 = call i32 @j() + ret i32 undef +} + +define internal i32 @j() #0 { +entry: + %i = alloca i32, align 4 + store i32 0, i32* %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %0 = load i32, i32* %i, align 4 + %1 = load i32, i32* @f, align 4 + %cmp = icmp ult i32 %0, %1 + br i1 %cmp, label %for.body, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.cond + %2 = load i32, i32* @f, align 4 + %call3 = call i32* @a(i32 %2) + ret i32 undef + +for.body: ; preds = %for.cond + %call = call i32 (...) @c() + %call1 = call i32 (...) @c() + %call2 = call i32 (...) @c() + %3 = load i32, i32* @b, align 4 + %4 = load i32, i32* @g, align 4 + %sub = sub nsw i32 %4, %3 + store i32 %sub, i32* @g, align 4 + %5 = load i32, i32* %i, align 4 + %inc = add i32 %5, 1 + store i32 %inc, i32* %i, align 4 + br label %for.cond +} + +declare i32 @c(...) #0 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #2 + +attributes #0 = { "use-soft-float"="false" } +attributes #1 = { "target-cpu"="x86-64" } +attributes #2 = { argmemonly nounwind } +