[llvm] [VectorCombine] Fix crash when folding select of bitcast (PR #177183)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 22 01:01:10 PST 2026


================
@@ -0,0 +1,93 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=vector-combine -S %s | FileCheck %s
+
+define i8 @fold_selects_from_bitcast_dominance(i8 %0) {
+; CHECK-LABEL: define i8 @fold_selects_from_bitcast_dominance(
+; CHECK-SAME: i8 [[TMP0:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[TMP0]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[COND]], <2 x i32> splat (i32 1), <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i32> [[TMP1]] to <8 x i8>
+; CHECK-NEXT:    [[SHIFT:%.*]] = shufflevector <8 x i8> [[TMP2]], <8 x i8> poison, <8 x i32> <i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT:    [[FOLDEXTEXTBINOP:%.*]] = add <8 x i8> [[TMP2]], [[SHIFT]]
+; CHECK-NEXT:    [[SHIFT2:%.*]] = shufflevector <8 x i8> [[TMP2]], <8 x i8> poison, <8 x i32> <i32 2, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT:    [[FOLDEXTEXTBINOP3:%.*]] = add <8 x i8> [[FOLDEXTEXTBINOP]], [[SHIFT2]]
+; CHECK-NEXT:    [[SHIFT5:%.*]] = shufflevector <8 x i8> [[TMP2]], <8 x i8> poison, <8 x i32> <i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT:    [[FOLDEXTEXTBINOP6:%.*]] = add <8 x i8> [[FOLDEXTEXTBINOP3]], [[SHIFT5]]
+; CHECK-NEXT:    [[SHIFT8:%.*]] = shufflevector <8 x i8> [[TMP2]], <8 x i8> poison, <8 x i32> <i32 4, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT:    [[FOLDEXTEXTBINOP9:%.*]] = add <8 x i8> [[FOLDEXTEXTBINOP6]], [[SHIFT8]]
+; CHECK-NEXT:    [[SHIFT11:%.*]] = shufflevector <8 x i8> [[TMP2]], <8 x i8> poison, <8 x i32> <i32 5, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT:    [[FOLDEXTEXTBINOP12:%.*]] = add <8 x i8> [[FOLDEXTEXTBINOP9]], [[SHIFT11]]
+; CHECK-NEXT:    [[SHIFT14:%.*]] = shufflevector <8 x i8> [[TMP2]], <8 x i8> poison, <8 x i32> <i32 6, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT:    [[FOLDEXTEXTBINOP15:%.*]] = add <8 x i8> [[FOLDEXTEXTBINOP12]], [[SHIFT14]]
+; CHECK-NEXT:    [[SHIFT17:%.*]] = shufflevector <8 x i8> [[TMP2]], <8 x i8> poison, <8 x i32> <i32 7, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT:    [[FOLDEXTEXTBINOP18:%.*]] = add <8 x i8> [[FOLDEXTEXTBINOP15]], [[SHIFT17]]
+; CHECK-NEXT:    [[SUM7:%.*]] = extractelement <8 x i8> [[FOLDEXTEXTBINOP18]], i64 0
+; CHECK-NEXT:    ret i8 [[SUM7]]
+;
+entry:
+  %bc = bitcast <2 x i32> splat (i32 1) to <8 x i8>
+  %e0 = extractelement <8 x i8> %bc, i64 0
+  %cond = icmp eq i8 %0, 0
+  %e1 = extractelement <8 x i8> %bc, i64 1
+  %e2 = extractelement <8 x i8> %bc, i64 2
+  %e3 = extractelement <8 x i8> %bc, i64 3
+  %e4 = extractelement <8 x i8> %bc, i64 4
+  %e5 = extractelement <8 x i8> %bc, i64 5
+  %e6 = extractelement <8 x i8> %bc, i64 6
+  %e7 = extractelement <8 x i8> %bc, i64 7
+  %s0 = select i1 %cond, i8 %e0, i8 0
+  %s1 = select i1 %cond, i8 %e1, i8 0
+  %s2 = select i1 %cond, i8 %e2, i8 0
+  %s3 = select i1 %cond, i8 %e3, i8 0
+  %s4 = select i1 %cond, i8 %e4, i8 0
+  %s5 = select i1 %cond, i8 %e5, i8 0
+  %s6 = select i1 %cond, i8 %e6, i8 0
+  %s7 = select i1 %cond, i8 %e7, i8 0
+  %sum0 = add i8 %s0, %s1
+  %sum1 = add i8 %sum0, %s2
+  %sum2 = add i8 %sum1, %s3
+  %sum3 = add i8 %sum2, %s4
+  %sum4 = add i8 %sum3, %s5
+  %sum5 = add i8 %sum4, %s6
+  %sum6 = add i8 %sum5, %s7
+  ret i8 %sum6
+}
+
+define i8 @fold_selects_from_bitcast_dominance_multiblock(i8 %in) {
+; CHECK-LABEL: define i8 @fold_selects_from_bitcast_dominance_multiblock(
+; CHECK-SAME: i8 [[IN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[FIRST:.*]]
+; CHECK:       [[FIRST]]:
+; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i8 [[IN]], 0
+; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[TOBOOL_NOT]], <4 x i64> splat (i64 1), <4 x i64> zeroinitializer
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i64> [[TMP0]] to <32 x i8>
+; CHECK-NEXT:    [[BRCOND:%.*]] = icmp slt i8 [[IN]], 7
+; CHECK-NEXT:    br i1 [[BRCOND]], label %[[THEN:.*]], label %[[ELSE:.*]]
+; CHECK:       [[THEN]]:
+; CHECK-NEXT:    [[NARROW8:%.*]] = extractelement <32 x i8> [[TMP1]], i64 0
+; CHECK-NEXT:    ret i8 [[NARROW8]]
+; CHECK:       [[ELSE]]:
+; CHECK-NEXT:    [[NARROW:%.*]] = extractelement <32 x i8> [[TMP1]], i64 0
+; CHECK-NEXT:    ret i8 [[NARROW]]
+;
+entry:
+  %0 = bitcast <4 x i64> splat (i64 1) to <32 x i8>
----------------
arsenm wrote:

The cross block def is this degenerate bitcast, can you use a non-constant value? 

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


More information about the llvm-commits mailing list