[llvm] dc2f9fe - [InstCombine] Fold constant byte stores to integer stores (#196740)

via llvm-commits llvm-commits at lists.llvm.org
Sun May 10 09:20:03 PDT 2026


Author: Pedro Lobo
Date: 2026-05-10T17:19:59+01:00
New Revision: dc2f9fe95f03c3c927eed3eecd33c376d43cec8d

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

LOG: [InstCombine] Fold constant byte stores to integer stores (#196740)

Byte constants are equivalent to integer constants when stored to
memory. Replacing them in store instructions reduces IR differences and
enables existing optimizations over integer constants.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
    llvm/test/Transforms/InstCombine/store.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index 0fe44d615acea..0e917fb55aa1e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -1578,6 +1578,13 @@ Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) {
   if (isa<UndefValue>(Val))
     return eraseInstFromFunction(SI);
 
+  // Replace byte constants with integer constants in stores.
+  Constant *C;
+  if (Val->getType()->isByteOrByteVectorTy() && match(Val, m_ImmConstant(C)))
+    return replaceOperand(
+        SI, 0,
+        ConstantExpr::getBitCast(C, Type::getIntFromByteType(C->getType())));
+
   if (!NullPointerIsDefined(SI.getFunction(), SI.getPointerAddressSpace()))
     if (Value *V = simplifyNonNullOperand(Ptr, /*HasDereferenceable=*/true))
       return replaceOperand(SI, 1, V);

diff  --git a/llvm/test/Transforms/InstCombine/store.ll b/llvm/test/Transforms/InstCombine/store.ll
index 45f16d874c04e..e2fc0fdcd456a 100644
--- a/llvm/test/Transforms/InstCombine/store.ll
+++ b/llvm/test/Transforms/InstCombine/store.ll
@@ -399,6 +399,117 @@ define void @store_select_with_null_gep(i1 %cond, ptr %p, i64 %off) {
   ret void
 }
 
+define void @store_const_b8(ptr %p) {
+; CHECK-LABEL: @store_const_b8(
+; CHECK-NEXT:    store i8 1, ptr [[P:%.*]], align 1
+; CHECK-NEXT:    ret void
+;
+  store b8 1, ptr %p
+  ret void
+}
+
+define void @store_const_v4b8_zero(ptr %p) {
+; CHECK-LABEL: @store_const_v4b8_zero(
+; CHECK-NEXT:    store <4 x i8> zeroinitializer, ptr [[P:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+  store <4 x b8> zeroinitializer, ptr %p
+  ret void
+}
+
+define void @store_const_v4b8_splat(ptr %p) {
+; CHECK-LABEL: @store_const_v4b8_splat(
+; CHECK-NEXT:    store <4 x i8> splat (i8 5), ptr [[P:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+  store <4 x b8> splat (b8 5), ptr %p
+  ret void
+}
+
+define void @store_const_v4b8_mixed(ptr %p) {
+; CHECK-LABEL: @store_const_v4b8_mixed(
+; CHECK-NEXT:    store <4 x i8> <i8 1, i8 poison, i8 3, i8 undef>, ptr [[P:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+  store <4 x b8> <b8 1, b8 poison, b8 3, b8 undef>, ptr %p
+  ret void
+}
+
+define void @store_const_v4b8_data(ptr %p) {
+; CHECK-LABEL: @store_const_v4b8_data(
+; CHECK-NEXT:    store <4 x i8> <i8 1, i8 2, i8 3, i8 4>, ptr [[P:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+  store <4 x b8> <b8 1, b8 2, b8 3, b8 4>, ptr %p
+  ret void
+}
+
+define void @store_const_nxv4b8_splat(ptr %p) {
+; CHECK-LABEL: @store_const_nxv4b8_splat(
+; CHECK-NEXT:    store <vscale x 4 x i8> splat (i8 5), ptr [[P:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+  store <vscale x 4 x b8> splat (b8 5), ptr %p
+  ret void
+}
+
+define void @store_const_nxv4b8_zero(ptr %p) {
+; CHECK-LABEL: @store_const_nxv4b8_zero(
+; CHECK-NEXT:    store <vscale x 4 x i8> zeroinitializer, ptr [[P:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+  store <vscale x 4 x b8> zeroinitializer, ptr %p
+  ret void
+}
+
+define void @store_const_b8_atomic(ptr %p) {
+; CHECK-LABEL: @store_const_b8_atomic(
+; CHECK-NEXT:    store atomic i8 42, ptr [[P:%.*]] unordered, align 1
+; CHECK-NEXT:    ret void
+;
+  store atomic b8 42, ptr %p unordered, align 1
+  ret void
+}
+
+define void @store_const_v4b8_atomic(ptr %p) {
+; CHECK-LABEL: @store_const_v4b8_atomic(
+; CHECK-NEXT:    store atomic <4 x i8> splat (i8 5), ptr [[P:%.*]] unordered, align 4
+; CHECK-NEXT:    ret void
+;
+  store atomic <4 x b8> splat (b8 5), ptr %p unordered, align 4
+  ret void
+}
+
+define void @store_const_b5(ptr %p) {
+; CHECK-LABEL: @store_const_b5(
+; CHECK-NEXT:    store i5 5, ptr [[P:%.*]], align 1
+; CHECK-NEXT:    ret void
+;
+  store b5 5, ptr %p, align 1
+  ret void
+}
+
+; Byte constants cannot represent pointer provenance.
+; Make sure we do not fold the bitcast and change the store type.
+define void @store_const_b64_from_ptr(ptr %p) {
+; CHECK-LABEL: @store_const_b64_from_ptr(
+; CHECK-NEXT:    store b64 bitcast (ptr @Unknown to b64), ptr [[P:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+  store b64 bitcast (ptr @Unknown to b64), ptr %p
+  ret void
+}
+
+; Only constants should be folded.
+define void @store_nonconst_b8(b8 %v, ptr %p) {
+; CHECK-LABEL: @store_nonconst_b8(
+; CHECK-NEXT:    store b8 [[V:%.*]], ptr [[P:%.*]], align 1
+; CHECK-NEXT:    ret void
+;
+  store b8 %v, ptr %p
+  ret void
+}
+
 !0 = !{!4, !4, i64 0}
 !1 = !{!"omnipotent char", !2}
 !2 = !{!"Simple C/C++ TBAA"}


        


More information about the llvm-commits mailing list