[llvm] [EarlyCSE] Support memset loads (PR #194268)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 27 10:54:44 PDT 2026
https://github.com/nataliakokoromyti updated https://github.com/llvm/llvm-project/pull/194268
>From 0865dc9c1021712d85d5276956973717ef1fe420 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Sun, 26 Apr 2026 15:22:51 -0700
Subject: [PATCH 1/3] support memset loads
---
llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 33 ++++++++++++++++++--
llvm/test/Transforms/EarlyCSE/memset-load.ll | 12 +++++++
2 files changed, 42 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/Transforms/EarlyCSE/memset-load.ll
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index ff3d55e5747e5..9994f35a7109c 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -821,6 +821,15 @@ class EarlyCSE {
Info.IsVolatile = false;
break;
}
+ } else if (isa<MemSetInst>(Inst) &&
+ (IntrID == Intrinsic::memset ||
+ IntrID == Intrinsic::memset_inline)) {
+ auto *MI = cast<MemIntrinsic>(Inst);
+ Info.PtrVal = MI->getDest();
+ Info.MatchingId = 0;
+ Info.ReadMem = false;
+ Info.WriteMem = true;
+ Info.IsVolatile = MI->isVolatile();
}
}
}
@@ -885,9 +894,9 @@ class EarlyCSE {
// field in the MemIntrinsicInfo structure. That field contains
// non-negative values only.
int getMatchingId() const {
- if (IntrID != 0)
- return Info.MatchingId;
- return -1;
+ if (IntrID == 0)
+ return -1;
+ return Info.MatchingId;
}
Value *getPointerOperand() const {
@@ -1226,6 +1235,24 @@ Value *EarlyCSE::getMatchingValue(LoadValue &InVal, ParseMemoryInst &MemInst,
unsigned CurrentGeneration) {
if (InVal.DefInst == nullptr)
return nullptr;
+ if (auto *MSI = dyn_cast<MemSetInst>(InVal.DefInst)) {
+ if (!MemInst.isLoad() || MemInst.isVolatile() || !MemInst.isUnordered())
+ return nullptr;
+ auto *Val = dyn_cast<ConstantInt>(MSI->getValue());
+ if (!Val || !Val->isZero())
+ return nullptr;
+ auto Len = MSI->getLengthInBytes();
+ if (!Len)
+ return nullptr;
+ TypeSize LoadSize = SQ.DL.getTypeStoreSize(MemInst.getValueType());
+ if (LoadSize.isScalable() || Len->ult(LoadSize.getFixedValue()))
+ return nullptr;
+ if (!isOperatingOnInvariantMemAt(MemInst.get(), InVal.Generation) &&
+ !isSameMemGeneration(InVal.Generation, CurrentGeneration, InVal.DefInst,
+ MemInst.get()))
+ return nullptr;
+ return Constant::getNullValue(MemInst.getValueType());
+ }
if (InVal.MatchingId != MemInst.getMatchingId())
return nullptr;
// We don't yet handle removing loads with ordering of any kind.
diff --git a/llvm/test/Transforms/EarlyCSE/memset-load.ll b/llvm/test/Transforms/EarlyCSE/memset-load.ll
new file mode 100644
index 0000000000000..bc962347d8661
--- /dev/null
+++ b/llvm/test/Transforms/EarlyCSE/memset-load.ll
@@ -0,0 +1,12 @@
+; RUN: opt -S -passes='early-cse<memssa>' < %s | FileCheck %s
+
+define ptr @load_from_zero_memset(ptr %p) {
+; CHECK-LABEL: @load_from_zero_memset(
+; CHECK: ret ptr null
+entry:
+ call void @llvm.memset.p0.i64(ptr %p, i8 0, i64 8, i1 false)
+ %v = load ptr, ptr %p, align 8
+ ret ptr %v
+}
+
+declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
>From 4bc996427226c558ead4c49d8d89ad3d731f3e83 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Mon, 27 Apr 2026 10:45:25 -0700
Subject: [PATCH 2/3] update test checks
---
llvm/test/Transforms/EarlyCSE/memset-load.ll | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Transforms/EarlyCSE/memset-load.ll b/llvm/test/Transforms/EarlyCSE/memset-load.ll
index bc962347d8661..3705b442c6f28 100644
--- a/llvm/test/Transforms/EarlyCSE/memset-load.ll
+++ b/llvm/test/Transforms/EarlyCSE/memset-load.ll
@@ -1,8 +1,13 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -passes='early-cse<memssa>' < %s | FileCheck %s
define ptr @load_from_zero_memset(ptr %p) {
-; CHECK-LABEL: @load_from_zero_memset(
-; CHECK: ret ptr null
+; CHECK-LABEL: define ptr @load_from_zero_memset(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[P]], i8 0, i64 8, i1 false)
+; CHECK-NEXT: ret ptr null
+;
entry:
call void @llvm.memset.p0.i64(ptr %p, i8 0, i64 8, i1 false)
%v = load ptr, ptr %p, align 8
>From 3ef733846290af57da96465dd49778984791f69d Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Mon, 27 Apr 2026 10:54:34 -0700
Subject: [PATCH 3/3] rm line
Co-authored-by: Antonio Frighetto <me at antoniofrighetto.com>
---
llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index 9994f35a7109c..b656b4f26df5b 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -823,7 +823,7 @@ class EarlyCSE {
}
} else if (isa<MemSetInst>(Inst) &&
(IntrID == Intrinsic::memset ||
- IntrID == Intrinsic::memset_inline)) {
+ } else if (isa<MemSetInst>(Inst)) {
auto *MI = cast<MemIntrinsic>(Inst);
Info.PtrVal = MI->getDest();
Info.MatchingId = 0;
More information about the llvm-commits
mailing list