[llvm] [VectorCombine] Scalarize binop-like intrinsics (PR #138095)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Fri May 2 21:23:13 PDT 2025


================
@@ -1135,9 +1167,16 @@ bool VectorCombine::scalarizeBinopOrCmp(Instruction &I) {
     ScalarInst->copyIRFlags(&I);
 
   // Fold the vector constants in the original vectors into a new base vector.
-  Value *NewVecC =
-      IsCmp ? Builder.CreateCmp(Pred, VecC0, VecC1)
-            : Builder.CreateBinOp((Instruction::BinaryOps)Opcode, VecC0, VecC1);
+  Value *NewVecC;
+  if (isa<CmpInst>(I))
+    NewVecC = Builder.CreateCmp(Pred, VecC0, VecC1);
+  else if (isa<BinaryOperator>(I))
+    NewVecC = Builder.CreateBinOp((Instruction::BinaryOps)Opcode, VecC0, VecC1);
----------------
lukel97 wrote:

I was looking at this yesterday, we already have some tests that are immediate UB in `test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll`:

```
define <2 x i64> @urem_constant_op0(i64 %x) {
; CHECK-LABEL: @urem_constant_op0(
; CHECK-NEXT:    [[BO_SCALAR:%.*]] = urem i64 5, [[X:%.*]]
; CHECK-NEXT:    [[BO:%.*]] = insertelement <2 x i64> poison, i64 [[BO_SCALAR]], i64 0
; CHECK-NEXT:    ret <2 x i64> [[BO]]
;
  %ins = insertelement <2 x i64> undef, i64 %x, i32 0
  %bo = urem <2 x i64> <i64 5, i64 undef>, %ins
  ret <2 x i64> %bo
}
```

I was thinking of opening up a separate PR to remove the UB here and separate tests if that works?

FWIW it looks like Builder.CreateBinOp currently folds the UB into element-wise poison, so coincidentally the transform is still correct, i.e. the `udiv <2 x i8> splat (i8 1), <i8 0, i8 1>` gets constant folded to `<i8 poison, i8 1>`:

```llvm 
define <2 x i8> @f(i8 %x) {
  %ins = insertelement <2 x i8> <i8 0, i8 1>, i8 %x, i32 0
  %v = udiv <2 x i8> splat (i8 1), %ins
  ret <2 x i8> %v
}
```

```llvm
define <2 x i8> @f(i8 %x) {
  %v.scalar = udiv i8 1, %x
  %v = insertelement <2 x i8> <i8 poison, i8 1>, i8 %v.scalar, i64 0
  ret <2 x i8> %v
}
```

But there's no guarantee Builder.CreateBinOp will produce that and we still need to fix that I guess.

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


More information about the llvm-commits mailing list