From d68800d15ddbfe4d014803c9695bc833895c1e66 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 3 Apr 2023 16:03:11 +0200 Subject: [PATCH] [Local] Preserve !invariant.load of dominating instruction Per LangRef: > If a load instruction tagged with the !invariant.load metadata > is executed, the memory location referenced by the load has to > contain the same value at all points in the program where the > memory location is dereferenceable; otherwise, the behavior is > undefined. As invariant.load violation is immediate undefined behavior, it is sufficient for it to be present on the dominating load (for the case where K does not move). --- llvm/lib/Transforms/Utils/Local.cpp | 6 ++++-- llvm/test/Transforms/GVN/PRE/invariant-load.ll | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index b32ed2a..c0d9569 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -2682,8 +2682,10 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J, K->setMetadata(Kind, MDNode::getMostGenericFPMath(JMD, KMD)); break; case LLVMContext::MD_invariant_load: - // Only set the !invariant.load if it is present in both instructions. - K->setMetadata(Kind, JMD); + // If K moves, only set the !invariant.load if it is present in both + // instructions. + if (DoesKMove) + K->setMetadata(Kind, JMD); break; case LLVMContext::MD_nonnull: if (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef)) diff --git a/llvm/test/Transforms/GVN/PRE/invariant-load.ll b/llvm/test/Transforms/GVN/PRE/invariant-load.ll index 3d01026..79cf951 100644 --- a/llvm/test/Transforms/GVN/PRE/invariant-load.ll +++ b/llvm/test/Transforms/GVN/PRE/invariant-load.ll @@ -187,7 +187,7 @@ define i32 @metadata_preservation(ptr nocapture %p, ptr nocapture %q) { ; CHECK-LABEL: define i32 @metadata_preservation ; CHECK-SAME: (ptr nocapture [[P:%.*]], ptr nocapture [[Q:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[P]], align 4, !invariant.load !0 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X]], [[X]] ; CHECK-NEXT: ret i32 [[ADD]] ; -- 2.7.4