[llvm] [ConstantFolding] Support bitcasting vectors to smaller element sizes with non-integer ratios. (PR #179640)
Kacper Doga via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 11 03:28:28 PST 2026
================
@@ -262,36 +261,65 @@ Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {
}
// Handle: bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>)
+ // bitcast (<3 x i64> <i64 0, i64 1, i64 2> to <8 x i24>)
unsigned Ratio = NumDstElt/NumSrcElt;
unsigned DstBitSize = DL.getTypeSizeInBits(DstEltTy);
-
- // Loop over each source value, expanding into multiple results.
- for (unsigned i = 0; i != NumSrcElt; ++i) {
- auto *Element = C->getAggregateElement(i);
-
+ APInt Rest(SrcBitSize, 0);
+ unsigned RestSize = 0;
+ for (unsigned i = 0; i != NumSrcElt || Result.size() != NumDstElt;) {
+ unsigned UnusedBits = SrcBitSize - RestSize;
+ if (RestSize == DstBitSize) {
+ // Shift the rest into the right place.
+ Rest.lshrInPlace(isLittleEndian ? UnusedBits : 0);
+ Result.push_back(ConstantInt::get(DstEltTy, Rest.trunc(DstBitSize)));
+ RestSize = 0;
+ Rest.clearAllBits();
+ continue;
+ }
+ auto *Element = C->getAggregateElement(i++);
if (!Element) // Reject constantexpr elements.
return ConstantExpr::getBitCast(C, DestTy);
+ APInt NextVecElem;
if (isa<UndefValue>(Element)) {
// Correctly Propagate undef values.
- Result.append(Ratio, UndefValue::get(DstEltTy));
- continue;
+ if (SrcBitSize % DstBitSize == 0) {
+ Result.append(Ratio, UndefValue::get(DstEltTy));
+ continue;
+ }
+ // Replace Undef with zeros to prevent partial corruption.
+ NextVecElem = APInt::getZero(SrcBitSize);
+ } else {
----------------
varev-dev wrote:
Also, I am not sure about this case. Should I append undefs or should I append zeros to make it coherent.
```cpp
if (SrcBitSize % DstBitSize == 0) {
Result.append(Ratio, UndefValue::get(DstEltTy));
continue;
}
```
https://github.com/llvm/llvm-project/pull/179640
More information about the llvm-commits
mailing list