[GVN] Propagate llvm.access.group metadata of loads
authorKAWASHIMA Takahiro <t-kawashima@fujitsu.com>
Wed, 31 Mar 2021 11:41:05 +0000 (20:41 +0900)
committerKAWASHIMA Takahiro <t-kawashima@fujitsu.com>
Thu, 1 Apr 2021 01:00:48 +0000 (10:00 +0900)
Before this change, the `llvm.access.group` metadata was dropped
when moving a load instruction in GVN. This prevents vectorizing
a C/C++ loop with `#pragma clang loop vectorize(assume_safety)`.
This change propagates the metadata as well as other metadata if
it is safe (the move-destination basic block and source basic
block belong to the same loop).

Differential Revision: https://reviews.llvm.org/D93503

llvm/lib/Transforms/Scalar/GVN.cpp
llvm/test/Transforms/GVN/PRE/load-pre-metadata-accsess-group.ll

index 65f7d04..ecfca80 100644 (file)
@@ -1406,6 +1406,10 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
       NewLoad->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
     if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range))
       NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
+    if (auto *AccessMD = LI->getMetadata(LLVMContext::MD_access_group))
+      if (this->LI && this->LI->getLoopFor(LI->getParent()) ==
+                          this->LI->getLoopFor(UnavailablePred))
+        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
index 5bbbf75..5cde83c 100644 (file)
@@ -20,7 +20,7 @@ define dso_local void @test1(i32* nocapture readonly %aa, i32* nocapture %bb) lo
 ; 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, i32* [[IDX]], align 4
+; CHECK-NEXT:    [[DOTPRE]] = load i32, i32* [[IDX]], align 4, !llvm.access.group !0
 ; CHECK-NEXT:    br label [[FOR_BODY]]
 ; CHECK:       for.end:
 ; CHECK-NEXT:    ret void
@@ -68,7 +68,7 @@ define dso_local void @test2(i32* nocapture readonly %aa, i32* nocapture %bb) lo
 ; CHECK-NEXT:    store i32 [[MUL]], i32* [[AA]], align 4, !llvm.access.group !1
 ; 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, i32* [[IDX]], align 4
+; CHECK-NEXT:    [[DOTPRE1]] = load i32, i32* [[IDX]], align 4, !llvm.access.group !1
 ; CHECK-NEXT:    br label [[FOR_BODY2]]
 ; CHECK:       for.end:
 ; CHECK-NEXT:    br i1 false, label [[FOR_END_FOR_BODY_CRIT_EDGE:%.*]], label [[END:%.*]]