From 059b1bbc06422d4941e67fee59a0f7a86a2aa7e0 Mon Sep 17 00:00:00 2001 From: Tommy McMichen Date: Thu, 31 Jul 2025 11:08:14 -0700 Subject: [PATCH 1/3] [llvm][sroa] Added test for `launder.invariant.group` inside of loop --- llvm/test/Transforms/SROA/invariant-group.ll | 38 ++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/llvm/test/Transforms/SROA/invariant-group.ll b/llvm/test/Transforms/SROA/invariant-group.ll index 1be6f6e2fc32b..4eac8fc1b48d6 100644 --- a/llvm/test/Transforms/SROA/invariant-group.ll +++ b/llvm/test/Transforms/SROA/invariant-group.ll @@ -155,6 +155,44 @@ define void @partial_promotion_of_alloca() { ret void } +define void @launder_in_loop() { +; CHECK-LABEL: @launder_in_loop( +; CHECK-NEXT: br label %[[HEADER:.*]] +; + %struct_ptr = alloca %t, i64 1, align 4 + br label %header + +; CHECK: [[HEADER]]: +; CHECK-NEXT: br i1 true, label %[[BODY:.*]], label %[[EXIT:.*]] +; +header: + br i1 true, label %body, label %exit + +; CHECK: [[BODY]]: +; CHECK-NEXT: [[STRUCT:%.*]] = call %t @make_t() +; CHECK-NEXT: [[FIRST:%.*]] = extractvalue %t [[STRUCT]], 0 +; CHECK-NEXT: [[SECOND:%.*]] = extractvalue %t [[STRUCT]], 1 +; CHECK-NEXT: br label %[[HEADER]] +; +body: ; preds = %6 + %struct_ptr_fresh = call ptr @llvm.launder.invariant.group.p0(ptr %struct_ptr) + %struct = call %t @make_t() + store %t %struct, ptr %struct_ptr_fresh, align 4, !invariant.group !0 + %first_ptr = getelementptr %t, ptr %struct_ptr_fresh, i32 0, i32 0 + %first = load i32, ptr %first_ptr, align 4 + %second_ptr = getelementptr %t, ptr %struct_ptr_fresh, i32 0, i32 1 + %second = load i32, ptr %second_ptr, align 4 + br label %header + +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +exit: + ret void +} + +declare %t @make_t() + declare void @use(ptr) !0 = !{} From 1c2e217e8e08f77712638d44696ce606b9540915 Mon Sep 17 00:00:00 2001 From: Tommy McMichen Date: Thu, 31 Jul 2025 11:11:34 -0700 Subject: [PATCH 2/3] [llvm][sroa] Added pass-through handling for launder/strip invariant group intrinsic in `AggLoadStoreRewriter` --- llvm/lib/Transforms/Scalar/SROA.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 23256cf2acbd2..821b41f0583f3 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -4261,6 +4261,12 @@ class AggLoadStoreRewriter : public InstVisitor { enqueueUsers(SI); return false; } + + bool visitIntrinsicInst(IntrinsicInst &II) { + if (II.isLaunderOrStripInvariantGroup()) + enqueueUsers(II); + return false; + } }; } // end anonymous namespace From a46f5fcac62ba6943122ab3b25834389b4cf133d Mon Sep 17 00:00:00 2001 From: Tommy McMichen Date: Fri, 1 Aug 2025 10:07:15 -0700 Subject: [PATCH 3/3] [llvm][sroa] Re-generated checks with update_test_check.py --- llvm/test/Transforms/SROA/invariant-group.ll | 23 +++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/llvm/test/Transforms/SROA/invariant-group.ll b/llvm/test/Transforms/SROA/invariant-group.ll index 4eac8fc1b48d6..9886217fb70d8 100644 --- a/llvm/test/Transforms/SROA/invariant-group.ll +++ b/llvm/test/Transforms/SROA/invariant-group.ll @@ -157,23 +157,23 @@ define void @partial_promotion_of_alloca() { define void @launder_in_loop() { ; CHECK-LABEL: @launder_in_loop( -; CHECK-NEXT: br label %[[HEADER:.*]] +; CHECK-NEXT: br label [[HEADER:%.*]] +; CHECK: header: +; CHECK-NEXT: br i1 true, label [[BODY:%.*]], label [[EXIT:%.*]] +; CHECK: body: +; CHECK-NEXT: [[STRUCT:%.*]] = call [[T:%.*]] @[[MAKE_T:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]]() +; CHECK-NEXT: [[STRUCT_FCA_0_EXTRACT:%.*]] = extractvalue [[T]] [[STRUCT]], 0 +; CHECK-NEXT: [[STRUCT_FCA_1_EXTRACT:%.*]] = extractvalue [[T]] [[STRUCT]], 1 +; CHECK-NEXT: br label [[HEADER]] +; CHECK: exit: +; CHECK-NEXT: ret void ; %struct_ptr = alloca %t, i64 1, align 4 br label %header -; CHECK: [[HEADER]]: -; CHECK-NEXT: br i1 true, label %[[BODY:.*]], label %[[EXIT:.*]] -; header: br i1 true, label %body, label %exit -; CHECK: [[BODY]]: -; CHECK-NEXT: [[STRUCT:%.*]] = call %t @make_t() -; CHECK-NEXT: [[FIRST:%.*]] = extractvalue %t [[STRUCT]], 0 -; CHECK-NEXT: [[SECOND:%.*]] = extractvalue %t [[STRUCT]], 1 -; CHECK-NEXT: br label %[[HEADER]] -; body: ; preds = %6 %struct_ptr_fresh = call ptr @llvm.launder.invariant.group.p0(ptr %struct_ptr) %struct = call %t @make_t() @@ -184,9 +184,6 @@ body: ; preds = %6 %second = load i32, ptr %second_ptr, align 4 br label %header -; CHECK: [[EXIT]]: -; CHECK-NEXT: ret void -; exit: ret void }