Skip to content

Commit 544f796

Browse files
committed
[GVN][JumpThreading] Try to salvage UB-implying metadata
1 parent 89b09c8 commit 544f796

File tree

3 files changed

+44
-18
lines changed

3 files changed

+44
-18
lines changed

llvm/lib/Transforms/Scalar/GVN.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,9 +1517,23 @@ void GVNPass::eliminatePartiallyRedundantLoad(
15171517
}
15181518

15191519
NewLoad->copyMetadata(*Load);
1520-
// Drop UB-implying metadata as we do not know if it is guaranteed to
1521-
// transfer the execution to the original load.
1522-
NewLoad->dropUBImplyingAttrsAndMetadata();
1520+
std::optional<bool> TransfersExecution = std::nullopt;
1521+
NewLoad->eraseMetadataIf([&](unsigned Kind, const MDNode *MD) {
1522+
if (Kind == LLVMContext::MD_dbg || Kind == LLVMContext::MD_annotation)
1523+
return false;
1524+
if (is_contained(Metadata::PoisonGeneratingIDs, Kind))
1525+
return false;
1526+
// Try to salvage UB-implying metadata if we know it is guaranteed to
1527+
// transfer the execution to the original load.
1528+
if (!TransfersExecution.has_value()) {
1529+
// TEST ONLY
1530+
assert(
1531+
is_contained(successors(NewLoad->getParent()), Load->getParent()));
1532+
TransfersExecution = isGuaranteedToTransferExecutionToSuccessor(
1533+
Load->getParent()->begin(), Load->getIterator());
1534+
}
1535+
return !*TransfersExecution;
1536+
});
15231537

15241538
// Add the newly created load.
15251539
ValuesPerBlock.push_back(

llvm/lib/Transforms/Scalar/JumpThreading.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,12 +1362,12 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
13621362
// farther than to a predecessor, we need to reuse the code from GVN's PRE.
13631363
// It requires domination tree analysis, so for this simple case it is an
13641364
// overkill.
1365-
bool TransfersExecution = false;
1365+
std::optional<bool> TransfersExecution = std::nullopt;
13661366
if (PredsScanned.size() != AvailablePreds.size() &&
13671367
!isSafeToSpeculativelyExecute(LoadI)) {
1368-
for (auto I = LoadBB->begin(); &*I != LoadI; ++I)
1369-
if (!isGuaranteedToTransferExecutionToSuccessor(&*I))
1370-
return false;
1368+
if (!isGuaranteedToTransferExecutionToSuccessor(LoadBB->begin(),
1369+
LoadI->getIterator()))
1370+
return false;
13711371
TransfersExecution = true;
13721372
}
13731373

@@ -1411,10 +1411,18 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
14111411
UnavailablePred->getTerminator()->getIterator());
14121412
NewVal->setDebugLoc(LoadI->getDebugLoc());
14131413
NewVal->copyMetadata(*LoadI);
1414-
// Drop UB-implying metadata if we do not know it is guaranteed to transfer
1415-
// the execution to the original load.
1416-
if (!TransfersExecution)
1417-
NewVal->dropUBImplyingAttrsAndMetadata();
1414+
NewVal->eraseMetadataIf([&](unsigned Kind, const MDNode *MD) {
1415+
if (Kind == LLVMContext::MD_dbg || Kind == LLVMContext::MD_annotation)
1416+
return false;
1417+
if (is_contained(Metadata::PoisonGeneratingIDs, Kind))
1418+
return false;
1419+
// Try to salvage UB-implying metadata if we know it is guaranteed to
1420+
// transfer the execution to the original load.
1421+
if (!TransfersExecution.has_value())
1422+
TransfersExecution = isGuaranteedToTransferExecutionToSuccessor(
1423+
LoadBB->begin(), LoadI->getIterator());
1424+
return !*TransfersExecution;
1425+
});
14181426

14191427
AvailablePreds.emplace_back(UnavailablePred, NewVal);
14201428
}

llvm/test/Transforms/GVN/pr64598.ll

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,23 @@ define i32 @main(i64 %x, ptr %d, ptr noalias %p) {
66
; CHECK-SAME: (i64 [[X:%.*]], ptr [[D:%.*]], ptr noalias [[P:%.*]]) {
77
; CHECK-NEXT: entry:
88
; CHECK-NEXT: [[T1_PRE_PRE_PRE:%.*]] = load ptr, ptr [[P]], align 8
9-
; CHECK-NEXT: [[T2_PRE_PRE_PRE:%.*]] = load ptr, ptr [[T1_PRE_PRE_PRE]], align 8
9+
; CHECK-NEXT: [[T2_PRE_PRE_PRE:%.*]] = load ptr, ptr [[T1_PRE_PRE_PRE]], align 8, !tbaa [[TBAA0:![0-9]+]]
1010
; CHECK-NEXT: [[T3_PRE_PRE_PRE:%.*]] = load ptr, ptr [[T2_PRE_PRE_PRE]], align 8
1111
; CHECK-NEXT: br label [[LOOP:%.*]]
1212
; CHECK: loop:
13-
; CHECK-NEXT: [[T1_PRE_PRE:%.*]] = phi ptr [ [[T1_PRE_PRE19:%.*]], [[LOOP_LATCH:%.*]] ], [ [[T1_PRE_PRE_PRE]], [[ENTRY:%.*]] ]
13+
; CHECK-NEXT: [[T2_PRE_PRE:%.*]] = phi ptr [ [[T2_PRE_PRE23:%.*]], [[LOOP_LATCH:%.*]] ], [ [[T2_PRE_PRE_PRE]], [[ENTRY:%.*]] ]
14+
; CHECK-NEXT: [[T1_PRE_PRE:%.*]] = phi ptr [ [[T1_PRE_PRE19:%.*]], [[LOOP_LATCH]] ], [ [[T1_PRE_PRE_PRE]], [[ENTRY]] ]
1415
; CHECK-NEXT: br label [[LOOP2:%.*]]
1516
; CHECK: loop2:
16-
; CHECK-NEXT: [[T1_PRE_PRE21:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE:%.*]] ], [ [[T1_PRE_PRE]], [[LOOP]] ]
17+
; CHECK-NEXT: [[T2_PRE_PRE25:%.*]] = phi ptr [ [[T2_PRE_PRE23]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE:%.*]] ], [ [[T2_PRE_PRE]], [[LOOP]] ]
18+
; CHECK-NEXT: [[T1_PRE_PRE21:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T1_PRE_PRE]], [[LOOP]] ]
1719
; CHECK-NEXT: [[T3_PRE:%.*]] = phi ptr [ [[T3_PRE16:%.*]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T3_PRE_PRE_PRE]], [[LOOP]] ]
18-
; CHECK-NEXT: [[T2_PRE:%.*]] = phi ptr [ [[T2_PRE13:%.*]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T2_PRE_PRE_PRE]], [[LOOP]] ]
20+
; CHECK-NEXT: [[T2_PRE:%.*]] = phi ptr [ [[T2_PRE13:%.*]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T2_PRE_PRE]], [[LOOP]] ]
1921
; CHECK-NEXT: [[T1_PRE:%.*]] = phi ptr [ [[T1_PRE10:%.*]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T1_PRE_PRE]], [[LOOP]] ]
2022
; CHECK-NEXT: br label [[LOOP3:%.*]]
2123
; CHECK: loop3:
22-
; CHECK-NEXT: [[T1_PRE_PRE20:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP3_LATCH:%.*]] ], [ [[T1_PRE_PRE21]], [[LOOP2]] ]
24+
; CHECK-NEXT: [[T2_PRE_PRE24:%.*]] = phi ptr [ [[T2_PRE_PRE23]], [[LOOP3_LATCH:%.*]] ], [ [[T2_PRE_PRE25]], [[LOOP2]] ]
25+
; CHECK-NEXT: [[T1_PRE_PRE20:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP3_LATCH]] ], [ [[T1_PRE_PRE21]], [[LOOP2]] ]
2326
; CHECK-NEXT: [[T3_PRE17:%.*]] = phi ptr [ [[T3_PRE16]], [[LOOP3_LATCH]] ], [ [[T3_PRE]], [[LOOP2]] ]
2427
; CHECK-NEXT: [[T2_PRE14:%.*]] = phi ptr [ [[T2_PRE13]], [[LOOP3_LATCH]] ], [ [[T2_PRE]], [[LOOP2]] ]
2528
; CHECK-NEXT: [[T1_PRE11:%.*]] = phi ptr [ [[T1_PRE10]], [[LOOP3_LATCH]] ], [ [[T1_PRE]], [[LOOP2]] ]
@@ -33,10 +36,11 @@ define i32 @main(i64 %x, ptr %d, ptr noalias %p) {
3336
; CHECK: for.body.lr.ph.i:
3437
; CHECK-NEXT: store i32 0, ptr [[P]], align 4
3538
; CHECK-NEXT: [[T5_PRE:%.*]] = load ptr, ptr [[P]], align 8
36-
; CHECK-NEXT: [[T6_PRE:%.*]] = load ptr, ptr [[T5_PRE]], align 8
39+
; CHECK-NEXT: [[T6_PRE:%.*]] = load ptr, ptr [[T5_PRE]], align 8, !tbaa [[TBAA0]]
3740
; CHECK-NEXT: [[T7_PRE:%.*]] = load ptr, ptr [[T6_PRE]], align 8
3841
; CHECK-NEXT: br label [[LOOP3_LATCH]]
3942
; CHECK: loop3.latch:
43+
; CHECK-NEXT: [[T2_PRE_PRE23]] = phi ptr [ [[T2_PRE_PRE24]], [[LOOP3_LOOP3_LATCH_CRIT_EDGE]] ], [ [[T6_PRE]], [[FOR_BODY_LR_PH_I]] ]
4044
; CHECK-NEXT: [[T1_PRE_PRE19]] = phi ptr [ [[T1_PRE_PRE20]], [[LOOP3_LOOP3_LATCH_CRIT_EDGE]] ], [ [[T5_PRE]], [[FOR_BODY_LR_PH_I]] ]
4145
; CHECK-NEXT: [[T3_PRE16]] = phi ptr [ [[T3_PRE17]], [[LOOP3_LOOP3_LATCH_CRIT_EDGE]] ], [ [[T7_PRE]], [[FOR_BODY_LR_PH_I]] ]
4246
; CHECK-NEXT: [[T2_PRE13]] = phi ptr [ [[T2_PRE14]], [[LOOP3_LOOP3_LATCH_CRIT_EDGE]] ], [ [[T6_PRE]], [[FOR_BODY_LR_PH_I]] ]
@@ -50,7 +54,7 @@ define i32 @main(i64 %x, ptr %d, ptr noalias %p) {
5054
; CHECK: loop2.latch.loop2_crit_edge:
5155
; CHECK-NEXT: br label [[LOOP2]]
5256
; CHECK: loop.latch:
53-
; CHECK-NEXT: store i32 0, ptr [[D]], align 4, !tbaa [[TBAA0:![0-9]+]]
57+
; CHECK-NEXT: store i32 0, ptr [[D]], align 4, !tbaa [[TBAA4:![0-9]+]]
5458
; CHECK-NEXT: br label [[LOOP]]
5559
;
5660
entry:

0 commit comments

Comments
 (0)