From 4fe38b59ff18090fb18a6263165877caad13b563 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Wed, 23 Jul 2025 09:02:55 +0100 Subject: [PATCH] [X86] getTargetConstantBitsFromNode - early-out if the element bitsize doesn't align with the source bitsize As we use getTargetConstantBitsFromNode in a wider variety of places we can't guarantee that all the sources match (or are legal) anymore - better to early out than assert. Fixes #150117 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 5 +- llvm/test/CodeGen/X86/vec_extract.ll | 66 +++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 568a8c4cfed79..11ab8dc685ea8 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5001,9 +5001,12 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits, EVT VT = Op.getValueType(); unsigned SizeInBits = VT.getSizeInBits(); - assert((SizeInBits % EltSizeInBits) == 0 && "Can't split constant!"); unsigned NumElts = SizeInBits / EltSizeInBits; + // Can't split constant. + if ((SizeInBits % EltSizeInBits) != 0) + return false; + // Bitcast a source array of element bits to the target size. auto CastBitData = [&](APInt &UndefSrcElts, ArrayRef SrcEltBits) { unsigned NumSrcElts = UndefSrcElts.getBitWidth(); diff --git a/llvm/test/CodeGen/X86/vec_extract.ll b/llvm/test/CodeGen/X86/vec_extract.ll index 087cd30abee9b..9bd38db3e9c4c 100644 --- a/llvm/test/CodeGen/X86/vec_extract.ll +++ b/llvm/test/CodeGen/X86/vec_extract.ll @@ -104,6 +104,72 @@ entry: } declare <2 x double> @foo() +define i64 @pr150117(<31 x i8> %a0) nounwind { +; X86-LABEL: pr150117: +; X86: # %bb.0: +; X86-NEXT: pushl %ebx +; X86-NEXT: pushl %edi +; X86-NEXT: pushl %esi +; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movzbl {{[0-9]+}}(%esp), %esi +; X86-NEXT: movzbl {{[0-9]+}}(%esp), %edi +; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ebx +; X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; X86-NEXT: shll $8, %edx +; X86-NEXT: orl %ebx, %edx +; X86-NEXT: shll $8, %edi +; X86-NEXT: orl %esi, %edi +; X86-NEXT: shll $16, %ecx +; X86-NEXT: orl %edi, %ecx +; X86-NEXT: movl {{[0-9]+}}(%esp), %esi +; X86-NEXT: shll $24, %esi +; X86-NEXT: orl %ecx, %esi +; X86-NEXT: movd %esi, %xmm0 +; X86-NEXT: pinsrw $2, %edx, %xmm0 +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: shll $8, %ecx +; X86-NEXT: orl %eax, %ecx +; X86-NEXT: pinsrw $3, %ecx, %xmm0 +; X86-NEXT: movd %xmm0, %eax +; X86-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,1,1] +; X86-NEXT: movd %xmm0, %edx +; X86-NEXT: popl %esi +; X86-NEXT: popl %edi +; X86-NEXT: popl %ebx +; X86-NEXT: retl +; +; X64-LABEL: pr150117: +; X64: # %bb.0: +; X64-NEXT: movzbl {{[0-9]+}}(%rsp), %eax +; X64-NEXT: movzbl {{[0-9]+}}(%rsp), %ecx +; X64-NEXT: movzbl {{[0-9]+}}(%rsp), %edx +; X64-NEXT: movzbl {{[0-9]+}}(%rsp), %esi +; X64-NEXT: movzbl {{[0-9]+}}(%rsp), %edi +; X64-NEXT: movl {{[0-9]+}}(%rsp), %r8d +; X64-NEXT: shll $8, %r8d +; X64-NEXT: orl %edi, %r8d +; X64-NEXT: shll $8, %esi +; X64-NEXT: orl %edx, %esi +; X64-NEXT: shll $16, %ecx +; X64-NEXT: orl %esi, %ecx +; X64-NEXT: movl {{[0-9]+}}(%rsp), %edx +; X64-NEXT: shll $24, %edx +; X64-NEXT: orl %ecx, %edx +; X64-NEXT: movd %edx, %xmm0 +; X64-NEXT: pinsrw $2, %r8d, %xmm0 +; X64-NEXT: movl {{[0-9]+}}(%rsp), %ecx +; X64-NEXT: shll $8, %ecx +; X64-NEXT: orl %eax, %ecx +; X64-NEXT: pinsrw $3, %ecx, %xmm0 +; X64-NEXT: movq %xmm0, %rax +; X64-NEXT: retq + %shuffle = shufflevector <31 x i8> %a0, <31 x i8> zeroinitializer, <32 x i32> + %bitcast = bitcast <32 x i8> %shuffle to <4 x i64> + %elt = extractelement <4 x i64> %bitcast, i64 0 + ret i64 %elt +} + ; OSS-Fuzz #15662 ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=15662 define <4 x i32> @ossfuzz15662(ptr %in) {