[llvm] [X86] Don't treat vectors with elements wider than 64 bits as immediate-shiftable (PR #228840)
Doha Nam via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 4 00:00:12 PDT 2026
https://github.com/waroad created https://github.com/llvm/llvm-project/pull/228840
supportedVectorShiftWithImm accepted any simple 128/256/512-bit vector with
elements of at least 16 bits, including v1i128 and v2i128. X86 has no vector
shifts for such elements, but combineAdd's ADD(x,x) -> X86ISD::VSHLI(x,1)
fold (#161843) relies on this predicate and runs before type legalization.
It therefore created VSHLI nodes on v1i128/v2i128 that the type legalizer
cannot scalarize or split. The result was "Do not know how to custom type
legalize this operation!" (before #203237, "Do not know how to scalarize the
result of this operator!"), and a crash in release builds.
Reject elements wider than 64 bits.
Fixes #228829.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
>From d3715573ad0f311bcf528f70cf44385cb4bc9ac0 Mon Sep 17 00:00:00 2001
From: waroad <dohanam2 at illinois.edu>
Date: Sun, 4 Oct 2026 01:41:03 -0500
Subject: [PATCH] [X86] Don't treat vectors with elements wider than 64 bits as
immediate-shiftable
supportedVectorShiftWithImm accepted any simple 128/256/512-bit vector with
elements of at least 16 bits, including v1i128 and v2i128. X86 has no vector
shifts for such elements, but combineAdd's ADD(x,x) -> X86ISD::VSHLI(x,1)
fold (#161843) relies on this predicate and runs before type legalization.
It therefore created VSHLI nodes on v1i128/v2i128 that the type legalizer
cannot scalarize or split. The result was "Do not know how to custom type
legalize this operation!" (before #203237, "Do not know how to scalarize the
result of this operator!"), and a crash in release builds.
Reject elements wider than 64 bits.
Fixes #228829.
Co-Authored-By: Claude Opus 5.5 <noreply at anthropic.com>
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 2 +-
llvm/test/CodeGen/X86/combine-add.ll | 31 +++++++++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index ccd53f8aaaffed5..c278aad224c7f94 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -31114,7 +31114,7 @@ static bool supportedVectorShiftWithImm(EVT VT, const X86Subtarget &Subtarget,
if (!(VT.is128BitVector() || VT.is256BitVector() || VT.is512BitVector()))
return false;
- if (VT.getScalarSizeInBits() < 16)
+ if (VT.getScalarSizeInBits() < 16 || VT.getScalarSizeInBits() > 64)
return false;
if (VT.is512BitVector() && Subtarget.useAVX512Regs() &&
diff --git a/llvm/test/CodeGen/X86/combine-add.ll b/llvm/test/CodeGen/X86/combine-add.ll
index c9455d5c4db4bdf..03d7d5f055dae11 100644
--- a/llvm/test/CodeGen/X86/combine-add.ll
+++ b/llvm/test/CodeGen/X86/combine-add.ll
@@ -640,3 +640,34 @@ define i32 @add_adc_multi_use(i32 %0, i32 %1, i32 %2) nounwind {
%10 = add i32 %9, %6
ret i32 %10
}
+
+; Don't fold add(x,x) -> X86ISD::VSHLI(x,1) for elements wider than 64 bits.
+; https://github.com/llvm/llvm-project/issues/228829
+define <1 x i128> @combine_vec_add_self_v1i128(<1 x i128> %a) {
+; CHECK-LABEL: combine_vec_add_self_v1i128:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movq %rsi, %rdx
+; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: addq %rdi, %rax
+; CHECK-NEXT: adcq %rsi, %rdx
+; CHECK-NEXT: retq
+ %s = add <1 x i128> %a, %a
+ ret <1 x i128> %s
+}
+
+define <2 x i128> @combine_vec_add_self_v2i128(<2 x i128> %a) {
+; CHECK-LABEL: combine_vec_add_self_v2i128:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: addq %rsi, %rsi
+; CHECK-NEXT: adcq %rdx, %rdx
+; CHECK-NEXT: addq %rcx, %rcx
+; CHECK-NEXT: adcq %r8, %r8
+; CHECK-NEXT: movq %r8, 24(%rdi)
+; CHECK-NEXT: movq %rcx, 16(%rdi)
+; CHECK-NEXT: movq %rdx, 8(%rdi)
+; CHECK-NEXT: movq %rsi, (%rdi)
+; CHECK-NEXT: retq
+ %s = add <2 x i128> %a, %a
+ ret <2 x i128> %s
+}
More information about the llvm-commits
mailing list