[llvm] [JumpThreading][GVN] Copy metadata when inserting preload into preds (PR #134403)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 23 01:54:40 PDT 2025
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/134403
>From 447ccd294b097e23a044de543de77d627e5363fa Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 4 Apr 2025 23:51:46 +0800
Subject: [PATCH 1/5] [JumpThreading] Copy metadata when inserting preload into
preds
---
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index ba598d8415b18..a681036ea78ee 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1410,6 +1410,13 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
if (AATags)
NewVal->setAAMetadata(AATags);
+ if (auto *MD = LoadI->getMetadata(LLVMContext::MD_invariant_load))
+ NewVal->setMetadata(LLVMContext::MD_invariant_load, MD);
+ if (auto *InvGroupMD = LoadI->getMetadata(LLVMContext::MD_invariant_group))
+ NewVal->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
+ if (auto *RangeMD = LoadI->getMetadata(LLVMContext::MD_range))
+ NewVal->setMetadata(LLVMContext::MD_range, RangeMD);
+
AvailablePreds.emplace_back(UnavailablePred, NewVal);
}
>From 763c5847882246ee281e8206517c811eeb15f285 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 17 Apr 2025 17:48:59 +0800
Subject: [PATCH 2/5] [JumpThreading][GVN] Use `copyMetadataForLoad`
---
llvm/lib/Transforms/Scalar/GVN.cpp | 21 +-------------------
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 10 +---------
llvm/lib/Transforms/Utils/Local.cpp | 1 +
3 files changed, 3 insertions(+), 29 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 6233e8e2ee681..31bdbc95fc277 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1516,26 +1516,7 @@ 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?
+ copyMetadataForLoad(*NewLoad, *Load);
// Add the newly created load.
ValuesPerBlock.push_back(
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index a681036ea78ee..8d790648c2ef9 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1407,15 +1407,7 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
LoadI->getOrdering(), LoadI->getSyncScopeID(),
UnavailablePred->getTerminator()->getIterator());
NewVal->setDebugLoc(LoadI->getDebugLoc());
- if (AATags)
- NewVal->setAAMetadata(AATags);
-
- if (auto *MD = LoadI->getMetadata(LLVMContext::MD_invariant_load))
- NewVal->setMetadata(LLVMContext::MD_invariant_load, MD);
- if (auto *InvGroupMD = LoadI->getMetadata(LLVMContext::MD_invariant_group))
- NewVal->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
- if (auto *RangeMD = LoadI->getMetadata(LLVMContext::MD_range))
- NewVal->setMetadata(LLVMContext::MD_range, RangeMD);
+ copyMetadataForLoad(*NewVal, *LoadI);
AvailablePreds.emplace_back(UnavailablePred, NewVal);
}
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 2f3ea2266e07f..fab45b1dfb088 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3468,6 +3468,7 @@ void llvm::copyMetadataForLoad(LoadInst &Dest, const LoadInst &Source) {
case LLVMContext::MD_fpmath:
case LLVMContext::MD_tbaa_struct:
case LLVMContext::MD_invariant_load:
+ case LLVMContext::MD_invariant_group:
case LLVMContext::MD_alias_scope:
case LLVMContext::MD_noalias:
case LLVMContext::MD_nontemporal:
>From 673ab49f50a981e59d23eee13ce0b2af320836d1 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 18 Apr 2025 16:06:14 +0800
Subject: [PATCH 3/5] [JumpThreading] Add tests. NFC.
---
.../test/Transforms/JumpThreading/pre-load.ll | 52 ++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/JumpThreading/pre-load.ll b/llvm/test/Transforms/JumpThreading/pre-load.ll
index d9a2dc20a4189..eef7735acf448 100644
--- a/llvm/test/Transforms/JumpThreading/pre-load.ll
+++ b/llvm/test/Transforms/JumpThreading/pre-load.ll
@@ -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
@@ -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:%.*]]
@@ -82,3 +86,49 @@ 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
+}
+;.
+; CHECK: [[RNG0]] = !{i32 0, i32 2}
+; CHECK: [[META1]] = !{}
+;.
>From 89b09c80ebc1a198bf2eab81b5fcb9ba71a0f066 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 23 Apr 2025 15:01:45 +0800
Subject: [PATCH 4/5] [GVN][JumpThreading] Address review comments
---
llvm/lib/Transforms/Scalar/GVN.cpp | 5 +-
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 11 ++++-
llvm/lib/Transforms/Utils/Local.cpp | 1 -
.../MemoryDependenceAnalysis/InvariantLoad.ll | 12 ++---
.../invariant.group-bug.ll | 2 +-
.../test/Transforms/GVN/PRE/invariant-load.ll | 2 +-
llvm/test/Transforms/GVN/PRE/load-metadata.ll | 2 +-
.../PRE/load-pre-metadata-accsess-group.ll | 10 ++--
llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll | 2 +-
llvm/test/Transforms/GVN/pr64598.ll | 18 +++----
.../test/Transforms/JumpThreading/pre-load.ll | 48 +++++++++++++++++++
.../PhaseOrdering/X86/spurious-peeling.ll | 4 +-
12 files changed, 85 insertions(+), 32 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 31bdbc95fc277..cdf2cfa311c65 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1516,7 +1516,10 @@ void GVNPass::eliminatePartiallyRedundantLoad(
MSSAU->insertUse(cast<MemoryUse>(NewAccess), /*RenameUses=*/true);
}
- copyMetadataForLoad(*NewLoad, *Load);
+ 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(
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 8d790648c2ef9..4bad53bc13e07 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -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
@@ -1407,7 +1410,11 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
LoadI->getOrdering(), LoadI->getSyncScopeID(),
UnavailablePred->getTerminator()->getIterator());
NewVal->setDebugLoc(LoadI->getDebugLoc());
- copyMetadataForLoad(*NewVal, *LoadI);
+ 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);
}
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index fab45b1dfb088..2f3ea2266e07f 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3468,7 +3468,6 @@ void llvm::copyMetadataForLoad(LoadInst &Dest, const LoadInst &Source) {
case LLVMContext::MD_fpmath:
case LLVMContext::MD_tbaa_struct:
case LLVMContext::MD_invariant_load:
- case LLVMContext::MD_invariant_group:
case LLVMContext::MD_alias_scope:
case LLVMContext::MD_noalias:
case LLVMContext::MD_nontemporal:
diff --git a/llvm/test/Analysis/MemoryDependenceAnalysis/InvariantLoad.ll b/llvm/test/Analysis/MemoryDependenceAnalysis/InvariantLoad.ll
index e49db3d8c3e8e..e98b635dc6086 100644
--- a/llvm/test/Analysis/MemoryDependenceAnalysis/InvariantLoad.ll
+++ b/llvm/test/Analysis/MemoryDependenceAnalysis/InvariantLoad.ll
@@ -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:%.*]] ]
@@ -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
@@ -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:
@@ -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:
@@ -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:
diff --git a/llvm/test/Analysis/MemoryDependenceAnalysis/invariant.group-bug.ll b/llvm/test/Analysis/MemoryDependenceAnalysis/invariant.group-bug.ll
index c11191ee96d01..802c969eae2fb 100644
--- a/llvm/test/Analysis/MemoryDependenceAnalysis/invariant.group-bug.ll
+++ b/llvm/test/Analysis/MemoryDependenceAnalysis/invariant.group-bug.ll
@@ -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]]
diff --git a/llvm/test/Transforms/GVN/PRE/invariant-load.ll b/llvm/test/Transforms/GVN/PRE/invariant-load.ll
index 71332bf0e0bdb..98df8b45951b3 100644
--- a/llvm/test/Transforms/GVN/PRE/invariant-load.ll
+++ b/llvm/test/Transforms/GVN/PRE/invariant-load.ll
@@ -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]] ]
diff --git a/llvm/test/Transforms/GVN/PRE/load-metadata.ll b/llvm/test/Transforms/GVN/PRE/load-metadata.ll
index 415812be95b3a..b97854d576383 100644
--- a/llvm/test/Transforms/GVN/PRE/load-metadata.ll
+++ b/llvm/test/Transforms/GVN/PRE/load-metadata.ll
@@ -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
diff --git a/llvm/test/Transforms/GVN/PRE/load-pre-metadata-accsess-group.ll b/llvm/test/Transforms/GVN/PRE/load-pre-metadata-accsess-group.ll
index 148e308b116ed..303064f6d8586 100644
--- a/llvm/test/Transforms/GVN/PRE/load-pre-metadata-accsess-group.ll
+++ b/llvm/test/Transforms/GVN/PRE/load-pre-metadata-accsess-group.ll
@@ -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
@@ -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:%.*]]
diff --git a/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll b/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll
index 3df63beefea68..6f1a645ca0c84 100644
--- a/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll
+++ b/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll
@@ -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:
diff --git a/llvm/test/Transforms/GVN/pr64598.ll b/llvm/test/Transforms/GVN/pr64598.ll
index 902af984bce2b..e8e70a0edbd2e 100644
--- a/llvm/test/Transforms/GVN/pr64598.ll
+++ b/llvm/test/Transforms/GVN/pr64598.ll
@@ -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]] ]
@@ -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]] ]
@@ -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:
diff --git a/llvm/test/Transforms/JumpThreading/pre-load.ll b/llvm/test/Transforms/JumpThreading/pre-load.ll
index eef7735acf448..4a3a80372973a 100644
--- a/llvm/test/Transforms/JumpThreading/pre-load.ll
+++ b/llvm/test/Transforms/JumpThreading/pre-load.ll
@@ -128,6 +128,54 @@ 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]] = !{}
diff --git a/llvm/test/Transforms/PhaseOrdering/X86/spurious-peeling.ll b/llvm/test/Transforms/PhaseOrdering/X86/spurious-peeling.ll
index 438a93c735796..80e7afafc9790 100644
--- a/llvm/test/Transforms/PhaseOrdering/X86/spurious-peeling.ll
+++ b/llvm/test/Transforms/PhaseOrdering/X86/spurious-peeling.ll
@@ -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
>From 544f796aaf9c89e474928a3cca24c95647c09eb1 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 23 Apr 2025 16:53:16 +0800
Subject: [PATCH 5/5] [GVN][JumpThreading] Try to salvage UB-implying metadata
---
llvm/lib/Transforms/Scalar/GVN.cpp | 20 +++++++++++++---
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 24 +++++++++++++-------
llvm/test/Transforms/GVN/pr64598.ll | 18 +++++++++------
3 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index cdf2cfa311c65..1414f11e2412f 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1517,9 +1517,23 @@ void GVNPass::eliminatePartiallyRedundantLoad(
}
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();
+ std::optional<bool> TransfersExecution = std::nullopt;
+ NewLoad->eraseMetadataIf([&](unsigned Kind, const MDNode *MD) {
+ if (Kind == LLVMContext::MD_dbg || Kind == LLVMContext::MD_annotation)
+ return false;
+ if (is_contained(Metadata::PoisonGeneratingIDs, Kind))
+ return false;
+ // Try to salvage UB-implying metadata if we know it is guaranteed to
+ // transfer the execution to the original load.
+ if (!TransfersExecution.has_value()) {
+ // TEST ONLY
+ assert(
+ is_contained(successors(NewLoad->getParent()), Load->getParent()));
+ TransfersExecution = isGuaranteedToTransferExecutionToSuccessor(
+ Load->getParent()->begin(), Load->getIterator());
+ }
+ return !*TransfersExecution;
+ });
// Add the newly created load.
ValuesPerBlock.push_back(
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 4bad53bc13e07..e7f7f811febf6 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1362,12 +1362,12 @@ 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;
+ std::optional<bool> TransfersExecution = std::nullopt;
if (PredsScanned.size() != AvailablePreds.size() &&
!isSafeToSpeculativelyExecute(LoadI)) {
- for (auto I = LoadBB->begin(); &*I != LoadI; ++I)
- if (!isGuaranteedToTransferExecutionToSuccessor(&*I))
- return false;
+ if (!isGuaranteedToTransferExecutionToSuccessor(LoadBB->begin(),
+ LoadI->getIterator()))
+ return false;
TransfersExecution = true;
}
@@ -1411,10 +1411,18 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
UnavailablePred->getTerminator()->getIterator());
NewVal->setDebugLoc(LoadI->getDebugLoc());
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();
+ NewVal->eraseMetadataIf([&](unsigned Kind, const MDNode *MD) {
+ if (Kind == LLVMContext::MD_dbg || Kind == LLVMContext::MD_annotation)
+ return false;
+ if (is_contained(Metadata::PoisonGeneratingIDs, Kind))
+ return false;
+ // Try to salvage UB-implying metadata if we know it is guaranteed to
+ // transfer the execution to the original load.
+ if (!TransfersExecution.has_value())
+ TransfersExecution = isGuaranteedToTransferExecutionToSuccessor(
+ LoadBB->begin(), LoadI->getIterator());
+ return !*TransfersExecution;
+ });
AvailablePreds.emplace_back(UnavailablePred, NewVal);
}
diff --git a/llvm/test/Transforms/GVN/pr64598.ll b/llvm/test/Transforms/GVN/pr64598.ll
index e8e70a0edbd2e..902af984bce2b 100644
--- a/llvm/test/Transforms/GVN/pr64598.ll
+++ b/llvm/test/Transforms/GVN/pr64598.ll
@@ -6,20 +6,23 @@ 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
+; CHECK-NEXT: [[T2_PRE_PRE_PRE:%.*]] = load ptr, ptr [[T1_PRE_PRE_PRE]], align 8, !tbaa [[TBAA0:![0-9]+]]
; CHECK-NEXT: [[T3_PRE_PRE_PRE:%.*]] = load ptr, ptr [[T2_PRE_PRE_PRE]], align 8
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[T1_PRE_PRE:%.*]] = phi ptr [ [[T1_PRE_PRE19:%.*]], [[LOOP_LATCH:%.*]] ], [ [[T1_PRE_PRE_PRE]], [[ENTRY:%.*]] ]
+; 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: br label [[LOOP2:%.*]]
; CHECK: loop2:
-; CHECK-NEXT: [[T1_PRE_PRE21:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE:%.*]] ], [ [[T1_PRE_PRE]], [[LOOP]] ]
+; 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: [[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_PRE]], [[LOOP]] ]
+; CHECK-NEXT: [[T2_PRE:%.*]] = phi ptr [ [[T2_PRE13:%.*]], [[LOOP2_LATCH_LOOP2_CRIT_EDGE]] ], [ [[T2_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: [[T1_PRE_PRE20:%.*]] = phi ptr [ [[T1_PRE_PRE19]], [[LOOP3_LATCH:%.*]] ], [ [[T1_PRE_PRE21]], [[LOOP2]] ]
+; 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: [[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]] ]
@@ -33,10 +36,11 @@ 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
+; CHECK-NEXT: [[T6_PRE:%.*]] = load ptr, ptr [[T5_PRE]], align 8, !tbaa [[TBAA0]]
; 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]] ]
@@ -50,7 +54,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 [[TBAA0:![0-9]+]]
+; CHECK-NEXT: store i32 0, ptr [[D]], align 4, !tbaa [[TBAA4:![0-9]+]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
More information about the llvm-commits
mailing list