[llvm] [NFC][LICM] Precommit mishandled per-iteration scoped alias metadata (PR #223529)

Zach Goldthorpe via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 10:52:36 PDT 2026


https://github.com/zGoldthorpe updated https://github.com/llvm/llvm-project/pull/223529

>From 5ecf574033e8e8f889aa82c76a9bc8e4c55b5cb9 Mon Sep 17 00:00:00 2001
From: Zach Goldthorpe <Zach.Goldthorpe at amd.com>
Date: Mon, 14 Sep 2026 15:56:04 -0500
Subject: [PATCH 1/2] [NFC][LICM] Precommit mishandled per-iteration scoped
 alias metadata

---
 .../Transforms/LICM/scalar-promote-aa-tags.ll | 117 ++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/llvm/test/Transforms/LICM/scalar-promote-aa-tags.ll b/llvm/test/Transforms/LICM/scalar-promote-aa-tags.ll
index 468cc9d554f6c..46e1081015be5 100644
--- a/llvm/test/Transforms/LICM/scalar-promote-aa-tags.ll
+++ b/llvm/test/Transforms/LICM/scalar-promote-aa-tags.ll
@@ -2,6 +2,7 @@
 ; RUN: opt -aa-pipeline=tbaa,scoped-noalias-aa,basic-aa -passes='require<aa>,require<target-ir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s
 
 declare i32 @opaque(i32) memory(argmem: readwrite)
+declare void @llvm.experimental.noalias.scope.decl(metadata)
 
 define i32 @promotable.store_dominates_exit_block(i64 %idx, i1 %c, i1 %c2) {
 ; CHECK-LABEL: define i32 @promotable.store_dominates_exit_block(
@@ -408,6 +409,122 @@ exit:
   ret i32 %res
 }
 
+define i32 @not_promotable.per_iteration_noalias_scope(i64 %idx, i1 %c, i1 %c2) {
+; CHECK-LABEL: define i32 @not_promotable.per_iteration_noalias_scope(
+; CHECK-SAME: i64 [[IDX:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[PTR:%.*]] = alloca [4 x i32], align 4
+; CHECK-NEXT:    [[PTR_PROMOTED:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[V_INC1:%.*]] = phi i32 [ [[PTR_PROMOTED]], %[[ENTRY]] ], [ [[V_INC2:%.*]], %[[LATCH:.*]] ]
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IDX]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH]] ]
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata [[META8]])
+; CHECK-NEXT:    [[FPTR:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[IV]]
+; CHECK-NEXT:    br i1 [[C]], label %[[IF:.*]], label %[[ELSE:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    store i32 42, ptr [[FPTR]], align 4, !alias.scope [[META8]]
+; CHECK-NEXT:    br label %[[LATCH]]
+; CHECK:       [[ELSE]]:
+; CHECK-NEXT:    [[V_INC:%.*]] = add i32 [[V_INC1]], 1
+; CHECK-NEXT:    br i1 [[C2]], label %[[EXIT:.*]], label %[[LATCH]]
+; CHECK:       [[LATCH]]:
+; CHECK-NEXT:    [[V_INC2]] = phi i32 [ [[V_INC]], %[[ELSE]] ], [ [[V_INC1]], %[[IF]] ]
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    br label %[[LOOP]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    [[V_INC_LCSSA:%.*]] = phi i32 [ [[V_INC]], %[[ELSE]] ]
+; CHECK-NEXT:    store i32 [[V_INC_LCSSA]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    ret i32 [[RES]]
+;
+entry:
+  %ptr = alloca [4 x i32]
+  br label %loop
+
+loop:
+  %iv = phi i64 [ %idx, %entry ], [ %iv.next, %latch ]
+  call void @llvm.experimental.noalias.scope.decl(metadata !8)
+  %fptr = getelementptr i32, ptr %ptr, i64 %iv
+  br i1 %c, label %if, label %else
+
+if:
+  store i32 42, ptr %fptr, !alias.scope !8
+  br label %latch
+
+else:
+  %v = load i32, ptr %ptr, !noalias !8
+  %v.inc = add i32 %v, 1
+  store i32 %v.inc, ptr %ptr, !noalias !8
+  br i1 %c2, label %exit, label %latch
+
+latch:
+  %iv.next = add i64 %iv, 1
+  br label %loop
+
+exit:
+  %res = load i32, ptr %ptr
+  ret i32 %res
+}
+
+define i32 @not_promotable.per_iteration_alias_scope(i64 %idx, i1 %c, i1 %c2) {
+; CHECK-LABEL: define i32 @not_promotable.per_iteration_alias_scope(
+; CHECK-SAME: i64 [[IDX:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[PTR:%.*]] = alloca [4 x i32], align 4
+; CHECK-NEXT:    [[PTR_PROMOTED:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[V:%.*]] = phi i32 [ [[PTR_PROMOTED]], %[[ENTRY]] ], [ [[V_INC1:%.*]], %[[LATCH:.*]] ]
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IDX]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH]] ]
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata [[META8]])
+; CHECK-NEXT:    [[FPTR:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[IV]]
+; CHECK-NEXT:    br i1 [[C]], label %[[IF:.*]], label %[[ELSE:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    store i32 42, ptr [[FPTR]], align 4, !noalias [[META8]]
+; CHECK-NEXT:    br label %[[LATCH]]
+; CHECK:       [[ELSE]]:
+; CHECK-NEXT:    [[V_INC:%.*]] = add i32 [[V]], 1
+; CHECK-NEXT:    br i1 [[C2]], label %[[EXIT:.*]], label %[[LATCH]]
+; CHECK:       [[LATCH]]:
+; CHECK-NEXT:    [[V_INC1]] = phi i32 [ [[V_INC]], %[[ELSE]] ], [ [[V]], %[[IF]] ]
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    br label %[[LOOP]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    [[V_INC_LCSSA:%.*]] = phi i32 [ [[V_INC]], %[[ELSE]] ]
+; CHECK-NEXT:    store i32 [[V_INC_LCSSA]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    ret i32 [[RES]]
+;
+entry:
+  %ptr = alloca [4 x i32]
+  br label %loop
+
+loop:
+  %iv = phi i64 [ %idx, %entry ], [ %iv.next, %latch ]
+  call void @llvm.experimental.noalias.scope.decl(metadata !8)
+  %fptr = getelementptr i32, ptr %ptr, i64 %iv
+  br i1 %c, label %if, label %else
+
+if:
+  store i32 42, ptr %fptr, !noalias !8
+  br label %latch
+
+else:
+  %v = load i32, ptr %ptr, !alias.scope !8
+  %v.inc = add i32 %v, 1
+  store i32 %v.inc, ptr %ptr, !alias.scope !8
+  br i1 %c2, label %exit, label %latch
+
+latch:
+  %iv.next = add i64 %iv, 1
+  br label %loop
+
+exit:
+  %res = load i32, ptr %ptr
+  ret i32 %res
+}
+
 !0 = !{!4, !4, i64 0}
 !1 = !{!"omnipotent char", !2}
 !2 = !{!"Simple C/C++ TBAA"}

>From 323838b487f2093dd37c40816e50d98a123bad7c Mon Sep 17 00:00:00 2001
From: Zach Goldthorpe <Zach.Goldthorpe at amd.com>
Date: Mon, 21 Sep 2026 11:37:35 -0500
Subject: [PATCH 2/2] Add precommit test for noalias scope declared outside
 loop

---
 .../Transforms/LICM/scalar-promote-aa-tags.ll | 58 +++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/llvm/test/Transforms/LICM/scalar-promote-aa-tags.ll b/llvm/test/Transforms/LICM/scalar-promote-aa-tags.ll
index 46e1081015be5..d55f45111f835 100644
--- a/llvm/test/Transforms/LICM/scalar-promote-aa-tags.ll
+++ b/llvm/test/Transforms/LICM/scalar-promote-aa-tags.ll
@@ -467,6 +467,64 @@ exit:
   ret i32 %res
 }
 
+define i32 @promotable.noalias_scope_outside_loop(i64 %idx, i1 %c, i1 %c2) {
+; CHECK-LABEL: define i32 @promotable.noalias_scope_outside_loop(
+; CHECK-SAME: i64 [[IDX:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    [[PTR:%.*]] = alloca [4 x i32], align 4
+; CHECK-NEXT:    call void @llvm.experimental.noalias.scope.decl(metadata [[META8]])
+; CHECK-NEXT:    [[PTR_PROMOTED:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[V_INC2:%.*]] = phi i32 [ [[PTR_PROMOTED]], %[[ENTRY]] ], [ [[V_INC1:%.*]], %[[LATCH:.*]] ]
+; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IDX]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH]] ]
+; CHECK-NEXT:    [[FPTR:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[IV]]
+; CHECK-NEXT:    br i1 [[C]], label %[[IF:.*]], label %[[ELSE:.*]]
+; CHECK:       [[IF]]:
+; CHECK-NEXT:    store i32 42, ptr [[FPTR]], align 4, !alias.scope [[META8]]
+; CHECK-NEXT:    br label %[[LATCH]]
+; CHECK:       [[ELSE]]:
+; CHECK-NEXT:    [[V_INC:%.*]] = add i32 [[V_INC2]], 1
+; CHECK-NEXT:    br i1 [[C2]], label %[[EXIT:.*]], label %[[LATCH]]
+; CHECK:       [[LATCH]]:
+; CHECK-NEXT:    [[V_INC1]] = phi i32 [ [[V_INC]], %[[ELSE]] ], [ [[V_INC2]], %[[IF]] ]
+; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
+; CHECK-NEXT:    br label %[[LOOP]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    [[V_INC_LCSSA:%.*]] = phi i32 [ [[V_INC]], %[[ELSE]] ]
+; CHECK-NEXT:    store i32 [[V_INC_LCSSA]], ptr [[PTR]], align 4
+; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    ret i32 [[RES]]
+;
+entry:
+  %ptr = alloca [4 x i32]
+  call void @llvm.experimental.noalias.scope.decl(metadata !8)
+  br label %loop
+
+loop:
+  %iv = phi i64 [ %idx, %entry ], [ %iv.next, %latch ]
+  %fptr = getelementptr i32, ptr %ptr, i64 %iv
+  br i1 %c, label %if, label %else
+
+if:
+  store i32 42, ptr %fptr, !alias.scope !8
+  br label %latch
+
+else:
+  %v = load i32, ptr %ptr, !noalias !8
+  %v.inc = add i32 %v, 1
+  store i32 %v.inc, ptr %ptr, !noalias !8
+  br i1 %c2, label %exit, label %latch
+
+latch:
+  %iv.next = add i64 %iv, 1
+  br label %loop
+
+exit:
+  %res = load i32, ptr %ptr
+  ret i32 %res
+}
+
 define i32 @not_promotable.per_iteration_alias_scope(i64 %idx, i1 %c, i1 %c2) {
 ; CHECK-LABEL: define i32 @not_promotable.per_iteration_alias_scope(
 ; CHECK-SAME: i64 [[IDX:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) {



More information about the llvm-commits mailing list