llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-llvm-transforms Author: Madhur Amilkanthwar (madhur13490) <details> <summary>Changes</summary> When forwarding a wider load to a narrower load at an offset, GVN drops the wider load's metadata. !noalias and !alias.scope are independent of the load type and offset, and the wider load is not moved and still accesses the same memory, so they remain valid and are now kept instead of dropped. --- Full diff: https://github.com/llvm/llvm-project/pull/206417.diff 2 Files Affected: - (modified) llvm/lib/Transforms/Scalar/GVN.cpp (+5-3) - (modified) llvm/test/Transforms/GVN/rle-coerced-noalias.ll (+12-7) ``````````diff diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index a619dcc588350..517d33bfba103 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -1163,13 +1163,15 @@ Value *AvailableValue::MaterializeAdjustedValue(LoadInst *Load, // Drop all metadata that is not known to cause immediate UB on violation, // unless the load has !noundef, in which case all metadata violations // will be promoted to UB. - // TODO: We can combine noalias/alias.scope metadata here, because it is - // independent of the load type. + // !noalias and !alias.scope are kept: the load is not moved and still + // accesses the same memory, and these are independent of the load type + // and offset, so they remain valid for the coerced result. if (!CoercedLoad->hasMetadata(LLVMContext::MD_noundef)) CoercedLoad->dropUnknownNonDebugMetadata( {LLVMContext::MD_dereferenceable, LLVMContext::MD_dereferenceable_or_null, - LLVMContext::MD_invariant_load, LLVMContext::MD_invariant_group}); + LLVMContext::MD_invariant_load, LLVMContext::MD_invariant_group, + LLVMContext::MD_alias_scope, LLVMContext::MD_noalias}); LLVM_DEBUG(dbgs() << "GVN COERCED NONLOCAL LOAD:\nOffset: " << Offset << " " << *getCoercedLoadValue() << '\n' << *Res << '\n' diff --git a/llvm/test/Transforms/GVN/rle-coerced-noalias.ll b/llvm/test/Transforms/GVN/rle-coerced-noalias.ll index 277e054fdccd5..67f7f58543aa8 100644 --- a/llvm/test/Transforms/GVN/rle-coerced-noalias.ll +++ b/llvm/test/Transforms/GVN/rle-coerced-noalias.ll @@ -1,10 +1,10 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 ; RUN: opt -S -passes=gvn < %s | FileCheck %s -; When GVN coerces a wider load into a narrower load at an offset, it strips -; !noalias and !alias.scope from the surviving wider load. That load is -; unchanged and still accesses the same memory, so the metadata stays valid -; and should be kept. It is currently dropped. +; When GVN coerces a wider load into a narrower load at an offset, the wider +; load is not moved and still accesses the same memory. Its !noalias and +; !alias.scope are independent of the load type and offset, so they are +; preserved on the surviving wider load rather than dropped. target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -14,7 +14,7 @@ define i32 @noalias_dropped_local(ptr %p) { ; CHECK-LABEL: define i32 @noalias_dropped_local( ; CHECK-SAME: ptr [[P:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[WIDE:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: [[WIDE:%.*]] = load i32, ptr [[P]], align 4, !noalias [[META0:![0-9]+]] ; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 1 ; CHECK-NEXT: [[TMP0:%.*]] = lshr i32 [[WIDE]], 8 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 @@ -36,7 +36,7 @@ define i32 @alias_scope_dropped_local(ptr %p) { ; CHECK-LABEL: define i32 @alias_scope_dropped_local( ; CHECK-SAME: ptr [[P:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[WIDE:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: [[WIDE:%.*]] = load i32, ptr [[P]], align 4, !alias.scope [[META0]] ; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 1 ; CHECK-NEXT: [[TMP0:%.*]] = lshr i32 [[WIDE]], 8 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 @@ -60,7 +60,7 @@ define i32 @noalias_dropped_nonlocal(ptr %p) { ; CHECK-LABEL: define i32 @noalias_dropped_nonlocal( ; CHECK-SAME: ptr [[P:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[WIDE:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: [[WIDE:%.*]] = load i32, ptr [[P]], align 4, !noalias [[META0]] ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[WIDE]], 127 ; CHECK-NEXT: [[TMP0:%.*]] = lshr i32 [[WIDE]], 8 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 @@ -92,3 +92,8 @@ f: !2 = distinct !{!2, !"test domain"} !0 = !{!1} +;. +; CHECK: [[META0]] = !{[[META1:![0-9]+]]} +; CHECK: [[META1]] = distinct !{[[META1]], [[META2:![0-9]+]], !"scope A"} +; CHECK: [[META2]] = distinct !{[[META2]], !"test domain"} +;. `````````` </details> https://github.com/llvm/llvm-project/pull/206417 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
