Skip to content

[JumpThreading] Copy metadata when inserting preload into preds #134403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 4 additions & 20 deletions llvm/lib/Transforms/Scalar/GVN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1516,26 +1516,10 @@ void GVNPass::eliminatePartiallyRedundantLoad(
MSSAU->insertUse(cast<MemoryUse>(NewAccess), /*RenameUses=*/true);
}

// Transfer the old load's AA tags to the new load.
AAMDNodes Tags = Load->getAAMetadata();
if (Tags)
NewLoad->setAAMetadata(Tags);

if (auto *MD = Load->getMetadata(LLVMContext::MD_invariant_load))
NewLoad->setMetadata(LLVMContext::MD_invariant_load, MD);
if (auto *InvGroupMD = Load->getMetadata(LLVMContext::MD_invariant_group))
NewLoad->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
if (auto *RangeMD = Load->getMetadata(LLVMContext::MD_range))
NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
if (auto *AccessMD = Load->getMetadata(LLVMContext::MD_access_group))
if (LI->getLoopFor(Load->getParent()) == LI->getLoopFor(UnavailableBlock))
NewLoad->setMetadata(LLVMContext::MD_access_group, AccessMD);

// We do not propagate the old load's debug location, because the new
// load now lives in a different BB, and we want to avoid a jumpy line
// table.
// FIXME: How do we retain source locations without causing poor debugging
// behavior?
NewLoad->copyMetadata(*Load);
// Drop UB-implying metadata as we do not know if it is guaranteed to
// transfer the execution to the original load.
NewLoad->dropUBImplyingAttrsAndMetadata();

// Add the newly created load.
ValuesPerBlock.push_back(
Expand Down
12 changes: 9 additions & 3 deletions llvm/lib/Transforms/Scalar/JumpThreading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1362,11 +1362,14 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
// farther than to a predecessor, we need to reuse the code from GVN's PRE.
// It requires domination tree analysis, so for this simple case it is an
// overkill.
bool TransfersExecution = false;
if (PredsScanned.size() != AvailablePreds.size() &&
!isSafeToSpeculativelyExecute(LoadI))
!isSafeToSpeculativelyExecute(LoadI)) {
for (auto I = LoadBB->begin(); &*I != LoadI; ++I)
if (!isGuaranteedToTransferExecutionToSuccessor(&*I))
return false;
TransfersExecution = true;
}

// If there is exactly one predecessor where the value is unavailable, the
// already computed 'OneUnavailablePred' block is it. If it ends in an
Expand Down Expand Up @@ -1407,8 +1410,11 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
LoadI->getOrdering(), LoadI->getSyncScopeID(),
UnavailablePred->getTerminator()->getIterator());
NewVal->setDebugLoc(LoadI->getDebugLoc());
if (AATags)
NewVal->setAAMetadata(AATags);
NewVal->copyMetadata(*LoadI);
// Drop UB-implying metadata if we do not know it is guaranteed to transfer
// the execution to the original load.
if (!TransfersExecution)
NewVal->dropUBImplyingAttrsAndMetadata();

AvailablePreds.emplace_back(UnavailablePred, NewVal);
}
Expand Down
12 changes: 6 additions & 6 deletions llvm/test/Analysis/MemoryDependenceAnalysis/InvariantLoad.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ declare void @foo(ptr)
define i8 @test(i1 %cmp) {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[P:%.*]] = alloca i8
; CHECK-NEXT: store i8 5, ptr [[P]]
; CHECK-NEXT: [[P:%.*]] = alloca i8, align 1
; CHECK-NEXT: store i8 5, ptr [[P]], align 1
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[V:%.*]] = phi i8 [ 5, [[ENTRY:%.*]] ], [ -5, [[ALIVE:%.*]] ]
Expand All @@ -23,7 +23,7 @@ define i8 @test(i1 %cmp) {
; CHECK-NEXT: br label [[ALIVE]]
; CHECK: alive:
; CHECK-NEXT: [[I_2:%.*]] = phi i8 [ [[I]], [[HEADER]] ], [ [[I_1]], [[DEAD]] ]
; CHECK-NEXT: store i8 -5, ptr [[P]]
; CHECK-NEXT: store i8 -5, ptr [[P]], align 1
; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[P]], i8 0, i32 1, i1 false)
; CHECK-NEXT: [[I_INC]] = add i8 [[I_2]], 1
; CHECK-NEXT: [[CMP_LOOP:%.*]] = icmp ugt i8 [[I_INC]], 100
Expand Down Expand Up @@ -67,7 +67,7 @@ define i8 @test2(i1 %cmp, ptr %p) {
; CHECK-NEXT: call void @foo(ptr [[P]])
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[B2:%.*]], label [[B1:%.*]]
; CHECK: b1:
; CHECK-NEXT: [[RES2:%.*]] = load i8, ptr [[P]]
; CHECK-NEXT: [[RES2:%.*]] = load i8, ptr [[P]], align 1
; CHECK-NEXT: [[RES3:%.*]] = add i8 [[RES1]], [[RES2]]
; CHECK-NEXT: br label [[ALIVE:%.*]]
; CHECK: b2:
Expand Down Expand Up @@ -105,7 +105,7 @@ define i8 @test3(i1 %cmp, ptr %p) {
; CHECK-NEXT: call void @foo(ptr [[P]])
; CHECK-NEXT: br i1 [[CMP:%.*]], label [[B1:%.*]], label [[B2:%.*]]
; CHECK: b1:
; CHECK-NEXT: [[RES2:%.*]] = load i8, ptr [[P]]
; CHECK-NEXT: [[RES2:%.*]] = load i8, ptr [[P]], align 1
; CHECK-NEXT: [[RES3:%.*]] = add i8 [[RES1]], [[RES2]]
; CHECK-NEXT: br label [[ALIVE:%.*]]
; CHECK: b2:
Expand Down Expand Up @@ -148,7 +148,7 @@ define void @test4() null_pointer_is_valid {
; CHECK-NEXT: [[TMP4:%.*]] = fmul float [[TMP2]], [[TMP2]]
; CHECK-NEXT: [[INVAR_INC3]] = add nuw nsw i64 [[FUSION_INVAR_ADDRESS_DIM_0_03]], 1
; CHECK-NEXT: [[DOTPHI_TRANS_INSERT:%.*]] = getelementptr inbounds [2 x [1 x [4 x float]]], ptr null, i64 0, i64 [[INVAR_INC3]], i64 0, i64 2
; CHECK-NEXT: [[DOTPRE]] = load float, ptr [[DOTPHI_TRANS_INSERT]], align 4, !invariant.load !0
; CHECK-NEXT: [[DOTPRE]] = load float, ptr [[DOTPHI_TRANS_INSERT]], align 4
; CHECK-NEXT: br label [[FUSION_LOOP_HEADER_DIM_1_PREHEADER]]
;
entry:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ define void @fail(ptr noalias sret(i1) %arg, ptr %arg1, ptr %arg2, ptr %arg3, i1
; CHECK-NEXT: br i1 [[ARG4:%.*]], label [[BB10:%.*]], label [[BB29:%.*]]
; CHECK: bb10:
; CHECK-NEXT: [[I14_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds ptr, ptr [[I4]], i64 22
; CHECK-NEXT: [[I15_PRE:%.*]] = load ptr, ptr [[I14_PHI_TRANS_INSERT]], align 8, !invariant.load [[META6]]
; CHECK-NEXT: [[I15_PRE:%.*]] = load ptr, ptr [[I14_PHI_TRANS_INSERT]], align 8
; CHECK-NEXT: br label [[BB12:%.*]]
; CHECK: bb12:
; CHECK-NEXT: [[I16:%.*]] = call i64 [[I15_PRE]](ptr nonnull [[ARG1]], ptr null, i64 0) #[[ATTR1]]
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GVN/PRE/invariant-load.ll
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ define i32 @test8(i1 %cnd, ptr %p) {
; CHECK-NEXT: br i1 [[CND]], label [[TAKEN:%.*]], label [[MERGE:%.*]]
; CHECK: taken:
; CHECK-NEXT: [[P2:%.*]] = call ptr (...) @bar(ptr [[P]])
; CHECK-NEXT: [[V2_PRE:%.*]] = load i32, ptr [[P2]], align 4, !invariant.load [[META0]]
; CHECK-NEXT: [[V2_PRE:%.*]] = load i32, ptr [[P2]], align 4
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[V2:%.*]] = phi i32 [ [[V1]], [[ENTRY:%.*]] ], [ [[V2_PRE]], [[TAKEN]] ]
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GVN/PRE/load-metadata.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ block1:
block2:
br label %block4
; CHECK: block2:
; CHECK-NEXT: load i32, ptr %p, align 4, !range !0, !invariant.group !1
; CHECK-NEXT: load i32, ptr %p, align 4, !range !0

block3:
store i32 0, ptr %p
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/GVN/PRE/load-pre-metadata-accsess-group.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ define dso_local void @test1(ptr nocapture readonly %aa, ptr nocapture %bb) loca
; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[DOTPRE:%.*]], [[FOR_BODY_FOR_BODY_CRIT_EDGE:%.*]] ]
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY_FOR_BODY_CRIT_EDGE]] ]
; CHECK-NEXT: [[IDX4:%.*]] = getelementptr inbounds i32, ptr [[AA]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[IDX4]], align 4, !llvm.access.group !0
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[IDX4]], align 4, !llvm.access.group [[ACC_GRP0:![0-9]+]]
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[TMP2]]
; CHECK-NEXT: store i32 [[MUL]], ptr [[IDX4]], align 4, !llvm.access.group !0
; CHECK-NEXT: store i32 [[MUL]], ptr [[IDX4]], align 4, !llvm.access.group [[ACC_GRP0]]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 100
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE]], label [[FOR_END:%.*]]
; CHECK: for.body.for.body_crit_edge:
; CHECK-NEXT: [[DOTPRE]] = load i32, ptr [[IDX]], align 4, !llvm.access.group !0
; CHECK-NEXT: [[DOTPRE]] = load i32, ptr [[IDX]], align 4
; CHECK-NEXT: br label [[FOR_BODY]]
; CHECK: for.end:
; CHECK-NEXT: ret void
Expand Down Expand Up @@ -65,10 +65,10 @@ define dso_local void @test2(ptr nocapture readonly %aa, ptr nocapture %bb) loca
; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ [[DOTPRE]], [[FOR_BODY]] ], [ [[MUL:%.*]], [[FOR_BODY2_FOR_BODY2_CRIT_EDGE]] ]
; CHECK-NEXT: [[INDVARS2_IV:%.*]] = phi i64 [ 0, [[FOR_BODY]] ], [ 1, [[FOR_BODY2_FOR_BODY2_CRIT_EDGE]] ]
; CHECK-NEXT: [[MUL]] = mul nsw i32 [[TMP1]], [[TMP2]]
; CHECK-NEXT: store i32 [[MUL]], ptr [[AA]], align 4, !llvm.access.group !1
; CHECK-NEXT: store i32 [[MUL]], ptr [[AA]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]]
; CHECK-NEXT: br i1 true, label [[FOR_BODY2_FOR_BODY2_CRIT_EDGE]], label [[FOR_END:%.*]]
; CHECK: for.body2.for.body2_crit_edge:
; CHECK-NEXT: [[DOTPRE1]] = load i32, ptr [[IDX]], align 4, !llvm.access.group !1
; CHECK-NEXT: [[DOTPRE1]] = load i32, ptr [[IDX]], align 4
; CHECK-NEXT: br label [[FOR_BODY2]]
; CHECK: for.end:
; CHECK-NEXT: br i1 false, label [[FOR_END_FOR_BODY_CRIT_EDGE:%.*]], label [[END:%.*]]
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ target datalayout = "e-p:64:64:64"
; GVN should preserve the TBAA tag on loads when doing PRE.

; CHECK-LABEL: @test(
; CHECK: %tmp33.pre = load i16, ptr %P, align 2, !tbaa !0
; CHECK: %tmp33.pre = load i16, ptr %P, align 2
; CHECK: br label %for.body
define void @test(ptr %P, ptr %Q, i1 %arg) nounwind {
entry:
Expand Down
18 changes: 7 additions & 11 deletions llvm/test/Transforms/GVN/pr64598.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,20 @@ define i32 @main(i64 %x, ptr %d, ptr noalias %p) {
; CHECK-SAME: (i64 [[X:%.*]], ptr [[D:%.*]], ptr noalias [[P:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[T1_PRE_PRE_PRE:%.*]] = load ptr, ptr [[P]], align 8
; CHECK-NEXT: [[T2_PRE_PRE_PRE:%.*]] = load ptr, ptr [[T1_PRE_PRE_PRE]], align 8, !tbaa [[TBAA0:![0-9]+]]
; CHECK-NEXT: [[T2_PRE_PRE_PRE:%.*]] = load ptr, ptr [[T1_PRE_PRE_PRE]], align 8
; CHECK-NEXT: [[T3_PRE_PRE_PRE:%.*]] = load ptr, ptr [[T2_PRE_PRE_PRE]], align 8
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[T2_PRE_PRE:%.*]] = phi ptr [ [[T2_PRE_PRE23:%.*]], [[LOOP_LATCH:%.*]] ], [ [[T2_PRE_PRE_PRE]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[T1_PRE_PRE:%.*]] = phi ptr [ [[T1_PRE_PRE19:%.*]], [[LOOP_LATCH]] ], [ [[T1_PRE_PRE_PRE]], [[ENTRY]] ]
; CHECK-NEXT: [[T1_PRE_PRE:%.*]] = phi ptr [ [[T1_PRE_PRE19:%.*]], [[LOOP_LATCH:%.*]] ], [ [[T1_PRE_PRE_PRE]], [[ENTRY:%.*]] ]
; CHECK-NEXT: br label [[LOOP2:%.*]]
; CHECK: loop2:
; CHECK-NEXT: [[T2_PRE_PRE25:%.*]] = phi ptr [ [[T2_PRE_PRE23]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE:%.*]] ], [ [[T2_PRE_PRE]], [[LOOP]] ]
; CHECK-NEXT: [[T1_PRE_PRE21:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T1_PRE_PRE]], [[LOOP]] ]
; CHECK-NEXT: [[T1_PRE_PRE21:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE:%.*]] ], [ [[T1_PRE_PRE]], [[LOOP]] ]
; CHECK-NEXT: [[T3_PRE:%.*]] = phi ptr [ [[T3_PRE16:%.*]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T3_PRE_PRE_PRE]], [[LOOP]] ]
; CHECK-NEXT: [[T2_PRE:%.*]] = phi ptr [ [[T2_PRE13:%.*]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T2_PRE_PRE]], [[LOOP]] ]
; CHECK-NEXT: [[T2_PRE:%.*]] = phi ptr [ [[T2_PRE13:%.*]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T2_PRE_PRE_PRE]], [[LOOP]] ]
; CHECK-NEXT: [[T1_PRE:%.*]] = phi ptr [ [[T1_PRE10:%.*]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T1_PRE_PRE]], [[LOOP]] ]
; CHECK-NEXT: br label [[LOOP3:%.*]]
; CHECK: loop3:
; CHECK-NEXT: [[T2_PRE_PRE24:%.*]] = phi ptr [ [[T2_PRE_PRE23]], [[LOOP3_LATCH:%.*]] ], [ [[T2_PRE_PRE25]], [[LOOP2]] ]
; CHECK-NEXT: [[T1_PRE_PRE20:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP3_LATCH]] ], [ [[T1_PRE_PRE21]], [[LOOP2]] ]
; CHECK-NEXT: [[T1_PRE_PRE20:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP3_LATCH:%.*]] ], [ [[T1_PRE_PRE21]], [[LOOP2]] ]
; CHECK-NEXT: [[T3_PRE17:%.*]] = phi ptr [ [[T3_PRE16]], [[LOOP3_LATCH]] ], [ [[T3_PRE]], [[LOOP2]] ]
; CHECK-NEXT: [[T2_PRE14:%.*]] = phi ptr [ [[T2_PRE13]], [[LOOP3_LATCH]] ], [ [[T2_PRE]], [[LOOP2]] ]
; CHECK-NEXT: [[T1_PRE11:%.*]] = phi ptr [ [[T1_PRE10]], [[LOOP3_LATCH]] ], [ [[T1_PRE]], [[LOOP2]] ]
Expand All @@ -36,11 +33,10 @@ define i32 @main(i64 %x, ptr %d, ptr noalias %p) {
; CHECK: for.body.lr.ph.i:
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
; CHECK-NEXT: [[T5_PRE:%.*]] = load ptr, ptr [[P]], align 8
; CHECK-NEXT: [[T6_PRE:%.*]] = load ptr, ptr [[T5_PRE]], align 8, !tbaa [[TBAA0]]
; CHECK-NEXT: [[T6_PRE:%.*]] = load ptr, ptr [[T5_PRE]], align 8
; CHECK-NEXT: [[T7_PRE:%.*]] = load ptr, ptr [[T6_PRE]], align 8
; CHECK-NEXT: br label [[LOOP3_LATCH]]
; CHECK: loop3.latch:
; CHECK-NEXT: [[T2_PRE_PRE23]] = phi ptr [ [[T2_PRE_PRE24]], [[LOOP3_LOOP3_LATCH_CRIT_EDGE]] ], [ [[T6_PRE]], [[FOR_BODY_LR_PH_I]] ]
; CHECK-NEXT: [[T1_PRE_PRE19]] = phi ptr [ [[T1_PRE_PRE20]], [[LOOP3_LOOP3_LATCH_CRIT_EDGE]] ], [ [[T5_PRE]], [[FOR_BODY_LR_PH_I]] ]
; CHECK-NEXT: [[T3_PRE16]] = phi ptr [ [[T3_PRE17]], [[LOOP3_LOOP3_LATCH_CRIT_EDGE]] ], [ [[T7_PRE]], [[FOR_BODY_LR_PH_I]] ]
; CHECK-NEXT: [[T2_PRE13]] = phi ptr [ [[T2_PRE14]], [[LOOP3_LOOP3_LATCH_CRIT_EDGE]] ], [ [[T6_PRE]], [[FOR_BODY_LR_PH_I]] ]
Expand All @@ -54,7 +50,7 @@ define i32 @main(i64 %x, ptr %d, ptr noalias %p) {
; CHECK: loop2.latch.loop2_crit_edge:
; CHECK-NEXT: br label [[LOOP2]]
; CHECK: loop.latch:
; CHECK-NEXT: store i32 0, ptr [[D]], align 4, !tbaa [[TBAA4:![0-9]+]]
; CHECK-NEXT: store i32 0, ptr [[D]], align 4, !tbaa [[TBAA0:![0-9]+]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
Expand Down
100 changes: 99 additions & 1 deletion llvm/test/Transforms/JumpThreading/pre-load.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
; RUN: opt -passes=jump-threading -S < %s | FileCheck %s

@x = global i32 0
Expand All @@ -7,6 +7,10 @@
declare void @f()
declare void @g()

;.
; CHECK: @x = global i32 0
; CHECK: @y = global i32 0
;.
define i32 @pre(i1 %cond, i32 %n) {
; CHECK-LABEL: @pre(
; CHECK-NEXT: br i1 [[COND:%.*]], label [[C_THREAD:%.*]], label [[C:%.*]]
Expand Down Expand Up @@ -82,3 +86,97 @@ NO:
call void @g()
ret i32 1
}

define i32 @pre_metadata(i1 %cond) {
; CHECK-LABEL: @pre_metadata(
; CHECK-NEXT: br i1 [[COND:%.*]], label [[C_THREAD:%.*]], label [[C:%.*]]
; CHECK: C.thread:
; CHECK-NEXT: store i32 0, ptr @x, align 4
; CHECK-NEXT: br label [[YES:%.*]]
; CHECK: C:
; CHECK-NEXT: [[A_PR:%.*]] = load i32, ptr @y, align 4, !range [[RNG0:![0-9]+]], !noundef [[META1:![0-9]+]]
; CHECK-NEXT: [[COND2:%.*]] = icmp eq i32 [[A_PR]], 0
; CHECK-NEXT: br i1 [[COND2]], label [[YES]], label [[NO:%.*]]
; CHECK: YES:
; CHECK-NEXT: [[A4:%.*]] = phi i32 [ 0, [[C_THREAD]] ], [ [[A_PR]], [[C]] ]
; CHECK-NEXT: call void @f()
; CHECK-NEXT: ret i32 [[A4]]
; CHECK: NO:
; CHECK-NEXT: call void @g()
; CHECK-NEXT: ret i32 1
;
br i1 %cond, label %A, label %B

A:
store i32 0, ptr @x, align 4
br label %C

B:
br label %C

C:
%ptr = phi ptr [@x, %A], [@y, %B]
%a = load i32, ptr %ptr, align 4, !range !{i32 0, i32 2}, !noundef !{}
%cond2 = icmp eq i32 %a, 0
br i1 %cond2, label %YES, label %NO

YES:
call void @f()
ret i32 %a

NO:
call void @g()
ret i32 1
}

declare void @callee() memory(none)

define i32 @pre_metadata_may_throw_speculative(i1 %cond) {
; CHECK-LABEL: @pre_metadata_may_throw_speculative(
; CHECK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[C:%.*]]
; CHECK: C.thread:
; CHECK-NEXT: store i32 0, ptr @x, align 4
; CHECK-NEXT: call void @callee()
; CHECK-NEXT: br label [[YES:%.*]]
; CHECK: C:
; CHECK-NEXT: [[A_PR:%.*]] = load i32, ptr @x, align 4, !range [[RNG0]]
; CHECK-NEXT: call void @callee()
; CHECK-NEXT: [[COND2:%.*]] = icmp eq i32 [[A_PR]], 0
; CHECK-NEXT: br i1 [[COND2]], label [[YES]], label [[NO:%.*]]
; CHECK: YES:
; CHECK-NEXT: [[A3:%.*]] = phi i32 [ 0, [[A]] ], [ [[A_PR]], [[C]] ]
; CHECK-NEXT: call void @f()
; CHECK-NEXT: ret i32 [[A3]]
; CHECK: NO:
; CHECK-NEXT: call void @g()
; CHECK-NEXT: ret i32 1
;
br i1 %cond, label %A, label %B

A:
store i32 0, ptr @x, align 4
br label %C

B:
br label %C

C:
call void @callee()
%a = load i32, ptr @x, align 4, !range !{i32 0, i32 2}, !noundef !{}
%cond2 = icmp eq i32 %a, 0
br i1 %cond2, label %YES, label %NO

YES:
call void @f()
ret i32 %a

NO:
call void @g()
ret i32 1
}
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { memory(none) }
;.
; CHECK: [[RNG0]] = !{i32 0, i32 2}
; CHECK: [[META1]] = !{}
;.
4 changes: 2 additions & 2 deletions llvm/test/Transforms/PhaseOrdering/X86/spurious-peeling.ll
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ define dso_local void @_Z13vecIncFromPtrP12FloatVecPair(ptr %FVP) {
; O23-NEXT: [[ARRAYIDX_I4_I:%.*]] = getelementptr inbounds [[CLASS_HOMEMADEVECTOR_0]], ptr [[TMP3]], i64 undef
; O23-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARRAYIDX_I4_I]], align 8, !tbaa [[TBAA8]]
; O23-NEXT: [[ARRAYIDX_I5_I:%.*]] = getelementptr inbounds float, ptr [[TMP4]], i64 undef
; O23-NEXT: [[DOTPRE_I:%.*]] = load float, ptr [[ARRAYIDX_I5_I]], align 4, !tbaa [[TBAA9:![0-9]+]]
; O23-NEXT: [[DOTPRE_I:%.*]] = load float, ptr [[ARRAYIDX_I5_I]], align 4
; O23-NEXT: br label [[FOR_BODY7_I:%.*]]
; O23: for.body7.i:
; O23-NEXT: [[TMP5:%.*]] = phi float [ [[DOTPRE_I]], [[FOR_BODY7_LR_PH_I]] ], [ [[ADD_I:%.*]], [[FOR_BODY7_I]] ]
; O23-NEXT: [[J_07_I:%.*]] = phi i32 [ 0, [[FOR_BODY7_LR_PH_I]] ], [ [[INC_I:%.*]], [[FOR_BODY7_I]] ]
; O23-NEXT: [[TMP6:%.*]] = load float, ptr [[ARRAYIDX_I3_I]], align 4, !tbaa [[TBAA9]]
; O23-NEXT: [[TMP6:%.*]] = load float, ptr [[ARRAYIDX_I3_I]], align 4, !tbaa [[TBAA9:![0-9]+]]
; O23-NEXT: [[ADD_I]] = fadd float [[TMP5]], [[TMP6]]
; O23-NEXT: store float [[ADD_I]], ptr [[ARRAYIDX_I5_I]], align 4, !tbaa [[TBAA9]]
; O23-NEXT: [[INC_I]] = add nuw i32 [[J_07_I]], 1
Expand Down
Loading