[llvm] [ConstantFold] Support byte values in `bitcast` constant folding (PR #188030)

Pedro Lobo via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 19 03:44:09 PDT 2026


================
@@ -105,6 +106,68 @@ static Constant *foldConstVectorToAPInt(APInt &Result, Type *DestTy,
   return nullptr;
 }
 
+/// Check whether folding this bitcast into a byte vector would mix poison and
+/// non-poison bits in the same output lane. While integer types track poison on
+/// a per-value basis, byte types track it on a per-bit basis. However,
+/// `ConstantByte` cannot represent values with both poison and non-poison bits.
+///
+/// Source elements are grouped by the output lane they map to. Returns true if
+/// any group contains both poison and non-poison elements.
+static bool foldMixesPoisonBits(Constant *C, unsigned NumSrcElt,
+                                unsigned NumDstElt) {
+  unsigned Ratio = NumSrcElt / NumDstElt;
----------------
pedroclobo wrote:

The code performed some incorrect folds. For instance:

```llvm
define <3 x b8> @bitcast_constexpr_8b3_3b8_poison() {
; LE-LABEL: @bitcast_constexpr_8b3_3b8_poison(
; LE-NEXT:    ret <3 x b8> <b8 poison, b8 52, b8 -42>
;
; BE-LABEL: @bitcast_constexpr_8b3_3b8_poison(
; BE-NEXT:    ret <3 x b8> <b8 poison, b8 -89, b8 46>
;
  %res = bitcast <8 x b3> <b3 poison, b3 poison, b3 1, b3 2, b3 3, b3 4, b3 5, b3 6> to <3 x b8>
  ret <3 x b8> %res
}
```

Added a guard that bails out when element counts don't divide evenly and the source contains `poison`. Some of those casts could still be folded. I marked some of the tests with TODOs. I can address them in another PR.

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


More information about the llvm-commits mailing list