Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -453,6 +453,9 @@ LVI->eraseBlock(&BB); DeleteDeadBlock(&BB, DTU); Changed = true; + // The alias analysis may store dangling pointers to the deleted block, + // so we should not use it further. + AA = nullptr; continue; } @@ -473,6 +476,7 @@ // BB's parent until a DTU->getDomTree() event. LVI->eraseBlock(&BB); Changed = true; + AA = nullptr; } } } @@ -1982,6 +1986,7 @@ LVI->eraseBlock(SinglePred); MergeBasicBlockIntoOnlyPred(BB, DTU); + AA = nullptr; // Now that BB is merged into SinglePred (i.e. SinglePred code followed by // BB code within one basic block `BB`), we need to invalidate the LVI Index: llvm/test/Transforms/JumpThreading/pr43276.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/JumpThreading/pr43276.ll @@ -0,0 +1,88 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S < %s -jump-threading | FileCheck %s +; RUN: opt -S < %s -passes=jump-threading | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1" +target triple = "x86_64-unknown-linux-gnu" + +@global = external global i8* + +define i32 @wibble() { +; CHECK-LABEL: @wibble( +; CHECK-NEXT: bb19: +; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i8, i8* undef, i64 16 +; CHECK-NEXT: [[TMP21:%.*]] = load atomic i8*, i8** @global unordered, align 8 +; CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds i8, i8* [[TMP21]], i64 936 +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: br label [[BB3]] +; CHECK: bb3: +; CHECK-NEXT: [[TMP:%.*]] = phi i8* [ [[TMP22]], [[BB19:%.*]] ], [ undef, [[BB2:%.*]] ] +; CHECK-NEXT: [[TMP4:%.*]] = phi i8* [ [[TMP21]], [[BB19]] ], [ undef, [[BB2]] ] +; CHECK-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP]] to i64* +; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, i8* [[TMP4]], i64 848 +; CHECK-NEXT: [[TMP7:%.*]] = bitcast i8* [[TMP6]] to i8** +; CHECK-NEXT: br label [[BB11:%.*]] +; CHECK: bb11: +; CHECK-NEXT: [[TMP12:%.*]] = load atomic i8*, i8** [[TMP7]] unordered, align 8 +; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i8* [[TMP12]], null +; CHECK-NEXT: br i1 [[TMP13]], label [[BB17:%.*]], label [[BB16:%.*]] +; CHECK: bb16: +; CHECK-NEXT: store atomic i64 undef, i64* [[TMP5]] unordered, align 8 +; CHECK-NEXT: br label [[BB11]] +; CHECK: bb17: +; CHECK-NEXT: ret i32 undef +; +bb: + br label %bb1 + +bb1: ; preds = %bb + br label %bb18 + +bb2: ; No predecessors! + br label %bb3 + +bb3: ; preds = %bb19, %bb2 + %tmp = phi i8* [ %tmp22, %bb19 ], [ undef, %bb2 ] + %tmp4 = phi i8* [ %tmp21, %bb19 ], [ undef, %bb2 ] + %tmp5 = bitcast i8* %tmp to i64* + %tmp6 = getelementptr inbounds i8, i8* %tmp4, i64 848 + %tmp7 = bitcast i8* %tmp6 to i8** + br label %bb11 + +bb11: ; preds = %bb16, %bb3 + %tmp12 = load atomic i8*, i8** %tmp7 unordered, align 8 + %tmp13 = icmp eq i8* %tmp12, null + br i1 %tmp13, label %bb17, label %bb14 + +bb14: ; preds = %bb11 + br label %bb15 + +bb15: ; preds = %bb14 + br label %bb16 + +bb16: ; preds = %bb15 + store atomic i64 undef, i64* %tmp5 unordered, align 8 + br label %bb11 + +bb17: ; preds = %bb11 + ret i32 undef + +bb18: ; preds = %bb1 + br label %bb19 + +bb19: ; preds = %bb18 + %tmp20 = getelementptr i8, i8* undef, i64 16 + %tmp21 = load atomic i8*, i8** @global unordered, align 8 + %tmp22 = getelementptr inbounds i8, i8* %tmp21, i64 936 + br label %bb3 +} + +define void @zot(i8* align 8 dereferenceable_or_null(16) %arg, i32 %arg1) { +; CHECK-LABEL: @zot( +; CHECK-NEXT: bb: +; CHECK-NEXT: ret void +; +bb: + ret void +} Index: llvm/test/Transforms/JumpThreading/thread-loads.ll =================================================================== --- llvm/test/Transforms/JumpThreading/thread-loads.ll +++ llvm/test/Transforms/JumpThreading/thread-loads.ll @@ -466,10 +466,7 @@ ; CHECK-NEXT: store i32* [[CALL_I62]], i32** [[ARRAYIDX89]], align 8 ; CHECK-NEXT: [[L2:%.*]] = load i32, i32* [[ARRAYIDX185]], align 4 ; CHECK-NEXT: [[TOBOOL_I63:%.*]] = icmp eq i32 [[L2]], 0 -; CHECK-NEXT: br i1 [[TOBOOL_I63]], label [[SW_BB21_I_THREAD:%.*]], label [[IF_THEN_I64:%.*]] -; CHECK: sw.bb21.i.thread: -; CHECK-NEXT: store i32 10, i32* [[PHASE]], align 8 -; CHECK-NEXT: br label [[DO_BODY_PREHEADER_I67:%.*]] +; CHECK-NEXT: br i1 [[TOBOOL_I63]], label [[SW_BB21_I]], label [[IF_THEN_I64:%.*]] ; CHECK: if.then.i64: ; CHECK-NEXT: store i32 7, i32* [[PHASE]], align 8 ; CHECK-NEXT: store i32 [[L2]], i32* [[ARRAYIDX307]], align 4 @@ -480,10 +477,10 @@ ; CHECK-NEXT: call void @f65() ; CHECK-NEXT: br label [[SW_BB21_I]] ; CHECK: sw.bb21.i: -; CHECK-NEXT: [[L3_PR:%.*]] = load i32, i32* [[ARRAYIDX185]], align 4 ; CHECK-NEXT: store i32 10, i32* [[PHASE]], align 8 -; CHECK-NEXT: [[TOBOOL27_I:%.*]] = icmp eq i32 [[L3_PR]], 0 -; CHECK-NEXT: br i1 [[TOBOOL27_I]], label [[DO_BODY_PREHEADER_I67]], label [[CLEANUP]] +; CHECK-NEXT: [[L3:%.*]] = load i32, i32* [[ARRAYIDX185]], align 4 +; CHECK-NEXT: [[TOBOOL27_I:%.*]] = icmp eq i32 [[L3]], 0 +; CHECK-NEXT: br i1 [[TOBOOL27_I]], label [[DO_BODY_PREHEADER_I67:%.*]], label [[CLEANUP]] ; CHECK: do.body.preheader.i67: ; CHECK-NEXT: call void @f67() ; CHECK-NEXT: ret i32 67