[DAG] Prevent infinite loop combining bitcast shuffle

This prevents an infinite loop from D123801, where code trying to reduce
the total number of bitcasts, but also handling constants, could create
the opposite transform. Prevent the transform in these case to let the
bitcast of a constant transform naturally.

Fixes #55345
This commit is contained in:
David Green 2022-05-09 09:36:22 +01:00
parent d2c4ac979b
commit 02f8519502
3 changed files with 49 additions and 0 deletions

View File

@ -22043,6 +22043,12 @@ static SDValue combineShuffleOfBitcast(ShuffleVectorSDNode *SVN,
(!Op1.isUndef() && (Op1.getOpcode() != ISD::BITCAST ||
Op1.getOperand(0).getValueType() != InVT)))
return SDValue();
if ((ISD::isBuildVectorOfConstantSDNodes(Op0.getOperand(0).getNode()) ||
ISD::isBuildVectorOfConstantFPSDNodes(Op0.getOperand(0).getNode())) &&
(Op1.isUndef() ||
ISD::isBuildVectorOfConstantSDNodes(Op1.getOperand(0).getNode()) ||
ISD::isBuildVectorOfConstantFPSDNodes(Op1.getOperand(0).getNode())))
return SDValue();
int VTLanes = VT.getVectorNumElements();
int InLanes = InVT.getVectorNumElements();

View File

@ -56,6 +56,7 @@ define <4 x i32> @test_vmovrrd_combine() nounwind {
; CHECK-NEXT: bne .LBB3_2
; CHECK-NEXT: @ %bb.1: @ %bb1.preheader
; CHECK-NEXT: vmov.i32 q8, #0x0
; CHECK-NEXT: vext.8 q8, q8, q8, #4
; CHECK-NEXT: .LBB3_2: @ %bb2
; CHECK-NEXT: vmov r0, r1, d16
; CHECK-NEXT: vmov r2, r3, d17

View File

@ -0,0 +1,42 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx | FileCheck %s
; Make sure that we do not infinitely-loop combining shuffle vectors.
@test24_id5239 = dso_local local_unnamed_addr global i64 0, align 8
define void @infiloop() {
; CHECK-LABEL: infiloop:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movq %rsp, %rbp
; CHECK-NEXT: .cfi_def_cfa_register %rbp
; CHECK-NEXT: andq $-32, %rsp
; CHECK-NEXT: subq $64, %rsp
; CHECK-NEXT: movabsq $506097522914230528, %rax # imm = 0x706050403020100
; CHECK-NEXT: movq %rax, test24_id5239(%rip)
; CHECK-NEXT: vmovaps {{.*#+}} ymm0 = [4,1,6,7,6,7,2,3,6,7,4,5,6,7,2,3,6,7,2,3,2,3,2,3,4,5,4,5,2,3,0,1]
; CHECK-NEXT: vmovaps %ymm0, (%rsp)
; CHECK-NEXT: movq %rbp, %rsp
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: .cfi_def_cfa %rsp, 8
; CHECK-NEXT: vzeroupper
; CHECK-NEXT: retq
entry:
%id5230 = alloca <32 x i8>, align 32
store i8 0, ptr @test24_id5239, align 8
store i8 1, ptr getelementptr inbounds (i8, ptr @test24_id5239, i64 1), align 1
store i8 2, ptr getelementptr inbounds (i8, ptr @test24_id5239, i64 2), align 2
store i8 3, ptr getelementptr inbounds (i8, ptr @test24_id5239, i64 3), align 1
store i8 4, ptr getelementptr inbounds (i8, ptr @test24_id5239, i64 4), align 4
store i8 5, ptr getelementptr inbounds (i8, ptr @test24_id5239, i64 5), align 1
store i8 6, ptr getelementptr inbounds (i8, ptr @test24_id5239, i64 6), align 2
store i8 7, ptr getelementptr inbounds (i8, ptr @test24_id5239, i64 7), align 1
%0 = load <4 x i16>, ptr @test24_id5239, align 8
%shuffle = shufflevector <4 x i16> %0, <4 x i16> poison, <16 x i32> <i32 0, i32 3, i32 3, i32 1, i32 3, i32 2, i32 3, i32 1, i32 3, i32 1, i32 1, i32 1, i32 2, i32 2, i32 1, i32 0>
%1 = bitcast <16 x i16> %shuffle to <32 x i8>
%2 = or <32 x i8> %1, <i8 4, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>
store volatile <32 x i8> %2, ptr %id5230, align 32
ret void
}