[llvm] 14e8b98 - [InstCombine] Preserve access groups in mergeStoreIntoSuccessor (#214509)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 02:35:02 PDT 2026


Author: mikaoP
Date: 2026-08-11T09:34:57Z
New Revision: 14e8b98d179fd00fe5291c51678bbe5474bc419d

URL: https://github.com/llvm/llvm-project/commit/14e8b98d179fd00fe5291c51678bbe5474bc419d
DIFF: https://github.com/llvm/llvm-project/commit/14e8b98d179fd00fe5291c51678bbe5474bc419d.diff

LOG: [InstCombine] Preserve access groups in mergeStoreIntoSuccessor (#214509)

mergeStoreIntoSuccessor builds a fresh StoreInst and copies only
AAMDNodes, so !llvm.access.group is dropped even when both original
stores carry the same group.

llvm.loop.parallel_accesses is all-or-nothing: isAnnotatedParallel()
requires every memory operation in the loop to be a member, so one
untagged store de-parallelises the whole loop and LoopVectorize can
refuse a loop that is parallel by construction.

Added: 
    llvm/test/Transforms/InstCombine/storemerge-access-group.ll

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index edf046b32c32c..ae9082783c2bd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -16,6 +16,7 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/Loads.h"
+#include "llvm/Analysis/VectorUtils.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/LLVMContext.h"
@@ -1753,6 +1754,10 @@ bool InstCombinerImpl::mergeStoreIntoSuccessor(StoreInst &SI) {
   if (AATags)
     NewSI->setAAMetadata(AATags.merge(OtherStore->getAAMetadata()));
 
+  // If the two stores had access groups, intersect them.
+  NewSI->setMetadata(LLVMContext::MD_access_group,
+                     intersectAccessGroups(&SI, OtherStore));
+
   // Nuke the old stores.
   eraseInstFromFunction(SI);
   eraseInstFromFunction(*OtherStore);

diff  --git a/llvm/test/Transforms/InstCombine/storemerge-access-group.ll b/llvm/test/Transforms/InstCombine/storemerge-access-group.ll
new file mode 100644
index 0000000000000..9fac55f4473cd
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/storemerge-access-group.ll
@@ -0,0 +1,77 @@
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+; The store mergeStoreIntoSuccessor creates must keep the access groups both
+; original stores agree on, or the loop stops being annotated-parallel.
+
+; CHECK-LABEL: @merged_store_keeps_shared_access_group(
+; CHECK: store double %storemerge, ptr %q, align 8, !llvm.access.group [[ACC:![0-9]+]]
+define void @merged_store_keeps_shared_access_group(ptr noalias %dst, ptr noalias %src, i64 %n) {
+entry:
+  %guard = icmp sgt i64 %n, 0
+  br i1 %guard, label %loop, label %exit
+
+loop:
+  %i = phi i64 [ 0, %entry ], [ %i.next, %latch ]
+  %p = getelementptr inbounds double, ptr %src, i64 %i
+  %v = load double, ptr %p, align 8, !llvm.access.group !0
+  %q = getelementptr inbounds double, ptr %dst, i64 %i
+  %c = fcmp ogt double %v, 0.000000e+00
+  br i1 %c, label %then, label %else
+
+then:
+  store double %v, ptr %q, align 8, !llvm.access.group !0
+  br label %latch
+
+else:
+  store double 1.000000e+00, ptr %q, align 8, !llvm.access.group !0
+  br label %latch
+
+latch:
+  %i.next = add nuw nsw i64 %i, 1
+  %done = icmp eq i64 %i.next, %n
+  br i1 %done, label %exit, label %loop, !llvm.loop !1
+
+exit:
+  ret void
+}
+
+; If only one store is in the group, the merged store must not claim it.
+
+; CHECK-LABEL: @merged_store_drops_unshared_access_group(
+; CHECK: store double %storemerge, ptr %q, align 8
+; CHECK-NOT: !llvm.access.group
+define void @merged_store_drops_unshared_access_group(ptr noalias %dst, ptr noalias %src, i64 %n) {
+entry:
+  %guard = icmp sgt i64 %n, 0
+  br i1 %guard, label %loop, label %exit
+
+loop:
+  %i = phi i64 [ 0, %entry ], [ %i.next, %latch ]
+  %p = getelementptr inbounds double, ptr %src, i64 %i
+  %v = load double, ptr %p, align 8
+  %q = getelementptr inbounds double, ptr %dst, i64 %i
+  %c = fcmp ogt double %v, 0.000000e+00
+  br i1 %c, label %then, label %else
+
+then:
+  store double %v, ptr %q, align 8, !llvm.access.group !0
+  br label %latch
+
+else:
+  store double 1.000000e+00, ptr %q, align 8
+  br label %latch
+
+latch:
+  %i.next = add nuw nsw i64 %i, 1
+  %done = icmp eq i64 %i.next, %n
+  br i1 %done, label %exit, label %loop
+
+exit:
+  ret void
+}
+
+; CHECK: [[ACC]] = distinct !{}
+
+!0 = distinct !{}
+!1 = distinct !{!1, !2}
+!2 = !{!"llvm.loop.parallel_accesses", !0}


        


More information about the llvm-commits mailing list