[llvm] [ConstantFolding] Fix dropped bits in non-integer-ratio bitcast with undef lane (PR #202282)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 01:06:21 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: lijinpei-amd

<details>
<summary>Changes</summary>

When constant-folding a vector bitcast(e.g. <4 x i24> -> <3 x i32>), an undef source element inserted a DstBitSize-wide zero placeholder into the bit buffer. This could clobber defined source element, producing a wrong result on big-endian targets.

Fix by inserting SrcBitSize-wide zero instead.

Alive2 proof:
  before (unsound): https://alive2.llvm.org/ce/z/R_ZQ75
  after  (verified): https://alive2.llvm.org/ce/z/VuV3mz

---
Full diff: https://github.com/llvm/llvm-project/pull/202282.diff


2 Files Affected:

- (modified) llvm/lib/Analysis/ConstantFolding.cpp (+5-1) 
- (modified) llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll (+1-1) 


``````````diff
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 959b46f8eff46..4bb8bd8d7b583 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -359,7 +359,11 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
         UndefMask.setBits(BitPosition, BitPosition + SrcBitSize);
         if (isa<PoisonValue>(Element))
           PoisonMask.setBits(BitPosition, BitPosition + SrcBitSize);
-        SrcValue = APInt::getZero(DstBitSize);
+        // The placeholder value must be exactly SrcBitSize wide. Using a wider
+        // value here would clear DstBitSize bits via insertBits and clobber
+        // bits belonging to a previously loaded (defined) source element,
+        // producing an incorrect result for non-integer element ratios.
+        SrcValue = APInt::getZero(SrcBitSize);
       } else {
         auto *Src = dyn_cast<ConstantInt>(Element);
         if (!Src)
diff --git a/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll b/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll
index 88f34cabc6188..14789847911a5 100644
--- a/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll
+++ b/llvm/test/Transforms/InstSimplify/bitcast-vector-fold.ll
@@ -412,7 +412,7 @@ define <3 x i32> @bitcast_constexpr_3i32_4i24_n1255uu() {
 ; LE-NEXT:    ret <3 x i32> <i32 -1, i32 0, i32 undef>
 ;
 ; BE-LABEL: @bitcast_constexpr_3i32_4i24_n1255uu(
-; BE-NEXT:    ret <3 x i32> <i32 -256, i32 0, i32 undef>
+; BE-NEXT:    ret <3 x i32> <i32 -256, i32 16711680, i32 undef>
 ;
   %cast = bitcast <4 x i24><i24 -1, i24 255, i24 undef, i24 undef> to <3 x i32>
   ret <3 x i32> %cast

``````````

</details>


https://github.com/llvm/llvm-project/pull/202282


More information about the llvm-commits mailing list