[llvm] [ConstantFold] Support byte values in `bitcast` constant folding (PR #188030)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 5 09:48:34 PDT 2026
================
@@ -292,3 +292,195 @@ define <2 x i64> @bitcast_constexpr_4f32_2i64_1111() {
%res = bitcast <4 x float> splat (float 1.0) to <2 x i64>
ret <2 x i64> %res
}
+
+define <2 x b64> @bitcast_constexpr_16i8_2b64() {
+; CHECK-LABEL: @bitcast_constexpr_16i8_2b64(
+; CHECK-NEXT: ret <2 x b64> splat (b64 144680345676153346)
+;
+ %res = bitcast <16 x i8> splat (i8 2) to <2 x b64>
+ ret <2 x b64> %res
+}
+
+define <2 x b64> @bitcast_constexpr_16b8_2b64() {
+; CHECK-LABEL: @bitcast_constexpr_16b8_2b64(
+; CHECK-NEXT: ret <2 x b64> splat (b64 144680345676153346)
+;
+ %res = bitcast <16 x b8> splat (b8 2) to <2 x b64>
+ ret <2 x b64> %res
+}
+
+define <2 x i64> @bitcast_constexpr_4b32_2i64() {
+; CHECK-LABEL: @bitcast_constexpr_4b32_2i64(
+; CHECK-NEXT: ret <2 x i64> <i64 4294967296, i64 12884901890>
+;
+ %res = bitcast <4 x b32> <b32 0, b32 1, b32 2, b32 3> to <2 x i64>
+ ret <2 x i64> %res
+}
+
+define <4 x i32> @bitcast_constexpr_2b64_4i32() {
+; CHECK-LABEL: @bitcast_constexpr_2b64_4i32(
+; CHECK-NEXT: ret <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+;
+ %res = bitcast <2 x b64> <b64 0, b64 1> to <4 x i32>
+ ret <4 x i32> %res
+}
+
+define <2 x b64> @bitcast_constexpr_4i32_2b64() {
+; CHECK-LABEL: @bitcast_constexpr_4i32_2b64(
+; CHECK-NEXT: ret <2 x b64> <b64 4294967296, b64 12884901890>
+;
+ %res = bitcast <4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x b64>
+ ret <2 x b64> %res
+}
+
+define <4 x b32> @bitcast_constexpr_2i64_4b32() {
+; CHECK-LABEL: @bitcast_constexpr_2i64_4b32(
+; CHECK-NEXT: ret <4 x b32> <b32 0, b32 0, b32 1, b32 0>
+;
+ %res = bitcast <2 x i64> <i64 0, i64 1> to <4 x b32>
+ ret <4 x b32> %res
+}
+
+define <2 x b64> @bitcast_constexpr_4b32_2b64() {
+; CHECK-LABEL: @bitcast_constexpr_4b32_2b64(
+; CHECK-NEXT: ret <2 x b64> <b64 4294967296, b64 12884901890>
+;
+ %res = bitcast <4 x b32> <b32 0, b32 1, b32 2, b32 3> to <2 x b64>
+ ret <2 x b64> %res
+}
+
+define <16 x b8> @bitcast_constexpr_2b64_16b8() {
+; CHECK-LABEL: @bitcast_constexpr_2b64_16b8(
+; CHECK-NEXT: ret <16 x b8> <b8 0, b8 0, b8 0, b8 0, b8 0, b8 0, b8 0, b8 0, b8 1, b8 0, b8 0, b8 0, b8 0, b8 0, b8 0, b8 0>
+;
+ %res = bitcast <2 x b64> <b64 0, b64 1> to <16 x b8>
+ ret <16 x b8> %res
+}
+
+define <2 x i32> @bitcast_constexpr_scalar_b64_to_vector_2i32() {
+; CHECK-LABEL: @bitcast_constexpr_scalar_b64_to_vector_2i32(
+; CHECK-NEXT: ret <2 x i32> <i32 1, i32 0>
+;
+ %res = bitcast b64 1 to <2 x i32>
+ ret <2 x i32> %res
+}
+
+define <2 x b32> @bitcast_constexpr_scalar_i64_to_vector_2b32() {
+; CHECK-LABEL: @bitcast_constexpr_scalar_i64_to_vector_2b32(
+; CHECK-NEXT: ret <2 x b32> <b32 1, b32 0>
+;
+ %res = bitcast i64 1 to <2 x b32>
+ ret <2 x b32> %res
+}
+
+define <2 x b64> @bitcast_constexpr_4f32_2b64() {
+; CHECK-LABEL: @bitcast_constexpr_4f32_2b64(
+; CHECK-NEXT: ret <2 x b64> splat (b64 4575657222473777152)
+;
+ %res = bitcast <4 x float> splat (float 1.0) to <2 x b64>
+ ret <2 x b64> %res
+}
+
+define <4 x float> @bitcast_constexpr_2b64_4f32() {
+; CHECK-LABEL: @bitcast_constexpr_2b64_4f32(
+; CHECK-NEXT: ret <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0x36A0000000000000, float 0.000000e+00>
+;
+ %res = bitcast <2 x b64> <b64 0, b64 1> to <4 x float>
+ ret <4 x float> %res
+}
+
+define <2 x i64> @bitcast_constexpr_allones_4b32_2i64() {
+; CHECK-LABEL: @bitcast_constexpr_allones_4b32_2i64(
+; CHECK-NEXT: ret <2 x i64> splat (i64 -1)
+;
+ %res = bitcast <4 x b32> splat (b32 -1) to <2 x i64>
+ ret <2 x i64> %res
+}
+
+define <4 x i32> @bitcast_constexpr_allones_4b32_4i32() {
+; CHECK-LABEL: @bitcast_constexpr_allones_4b32_4i32(
+; CHECK-NEXT: ret <4 x i32> splat (i32 -1)
+;
+ %res = bitcast <4 x b32> splat (b32 -1) to <4 x i32>
+ ret <4 x i32> %res
+}
+
+define <4 x b32> @bitcast_constexpr_allones_2i64_4b32() {
+; CHECK-LABEL: @bitcast_constexpr_allones_2i64_4b32(
+; CHECK-NEXT: ret <4 x b32> splat (b32 -1)
+;
+ %res = bitcast <2 x i64> splat (i64 -1) to <4 x b32>
+ ret <4 x b32> %res
+}
+
+define <4 x b32> @bitcast_constexpr_allones_4i32_4b32() {
+; CHECK-LABEL: @bitcast_constexpr_allones_4i32_4b32(
+; CHECK-NEXT: ret <4 x b32> splat (b32 -1)
+;
+ %res = bitcast <4 x i32> splat (i32 -1) to <4 x b32>
+ ret <4 x b32> %res
+}
+
+define <2 x b64> @bitcast_constexpr_4b32_2b64_poison() {
+; CHECK-LABEL: @bitcast_constexpr_4b32_2b64_poison(
+; CHECK-NEXT: ret <2 x b64> bitcast (<4 x b32> <b32 poison, b32 1, b32 2, b32 3> to <2 x b64>)
+;
+ %res = bitcast <4 x b32> <b32 poison, b32 1, b32 2, b32 3> to <2 x b64>
+ ret <2 x b64> %res
+}
+
+define <2 x b64> @bitcast_constexpr_4i32_2b64_poison() {
+; CHECK-LABEL: @bitcast_constexpr_4i32_2b64_poison(
+; CHECK-NEXT: ret <2 x b64> bitcast (<4 x i32> <i32 0, i32 1, i32 poison, i32 3> to <2 x b64>)
+;
+ %res = bitcast <4 x i32> <i32 0, i32 1, i32 poison, i32 3> to <2 x b64>
+ ret <2 x b64> %res
+}
+
+define <2 x b64> @bitcast_constexpr_4f32_2b64_poison() {
+; CHECK-LABEL: @bitcast_constexpr_4f32_2b64_poison(
+; CHECK-NEXT: ret <2 x b64> bitcast (<4 x float> <float 1.000000e+00, float poison, float 2.000000e+00, float 3.000000e+00> to <2 x b64>)
+;
+ %res = bitcast <4 x float> <float 1.0, float poison, float 2.0, float 3.0> to <2 x b64>
+ ret <2 x b64> %res
+}
+
+define <2 x b64> @bitcast_constexpr_8b16_2b64_poison() {
+; CHECK-LABEL: @bitcast_constexpr_8b16_2b64_poison(
+; CHECK-NEXT: ret <2 x b64> bitcast (<8 x b16> <b16 0, b16 1, b16 2, b16 poison, b16 4, b16 5, b16 6, b16 7> to <2 x b64>)
+;
+ %res = bitcast <8 x b16> <b16 0, b16 1, b16 2, b16 poison, b16 4, b16 5, b16 6, b16 7> to <2 x b64>
+ ret <2 x b64> %res
+}
+
+define <2 x b64> @bitcast_constexpr_4b32_2b64_all_poison_group() {
+; CHECK-LABEL: @bitcast_constexpr_4b32_2b64_all_poison_group(
+; CHECK-NEXT: ret <2 x b64> <b64 0, b64 12884901890>
+;
+ %res = bitcast <4 x b32> <b32 poison, b32 poison, b32 2, b32 3> to <2 x b64>
+ ret <2 x b64> %res
+}
----------------
dtcxzyw wrote:
I prefer `b64 poison`.
> In such cases, I think the best we can do is not fold the cast, as we cannot express individual poison bits with ConstantByte.
Agree. Refinement in ConstantFolding is dangerous, as some threading optimizations just compare the result of constant folding (e.g., https://github.com/llvm/llvm-project/pull/114280).
https://github.com/llvm/llvm-project/pull/188030
More information about the llvm-commits
mailing list