llvm.org GIT mirror llvm / 703d953
Merging r250085: ------------------------------------------------------------------------ r250085 | Andrea_DiBiagio | 2015-10-12 15:22:30 -0400 (Mon, 12 Oct 2015) | 60 lines [x86] Fix wrong lowering of vsetcc nodes (PR25080). Function LowerVSETCC (in X86ISelLowering.cpp) worked under the wrong assumption that for non-AVX512 targets, the source type and destination type of a type-legalized setcc node were always the same type. This assumption was unfortunately incorrect; the type legalizer is not always able to promote the return type of a setcc to the same type as the first operand of a setcc. In the case of a vsetcc node, the legalizer firstly checks if the first input operand has a legal type. If so, then it promotes the return type of the vsetcc to that same type. Otherwise, the return type is promoted to the 'next legal type', which, for vectors of MVT::i1 is always a 128-bit integer vector type. Example (-mattr=+avx): %0 = trunc <8 x i32> %a to <8 x i23> %1 = icmp eq <8 x i23> %0, zeroinitializer The initial selection dag for the code above is: v8i1 = setcc t5, t7, seteq:ch t5: v8i23 = truncate t2 t2: v8i32,ch = CopyFromReg t0, Register:v8i32 %vreg1 t7: v8i32 = build_vector of all zeroes. The type legalizer would firstly check if 't5' has a legal type. If so, then it would reuse that same type to promote the return type of the setcc node. Unfortunately 't5' is of illegal type v8i23, and therefore it cannot be used to promote the return type of the setcc node. Consequently, the setcc return type is promoted to v8i16. Later on, 't5' is promoted to v8i32 thus leading to the following dag node: v8i16 = setcc t32, t25, seteq:ch where t32 and t25 are now values of type v8i32. Before this patch, function LowerVSETCC would have wrongly expanded the setcc to a single X86ISD::PCMPEQ. Surprisingly, ISel was still able to match an instruction. In our case, ISel would have matched a VPCMPEQWrr: t37: v8i16 = X86ISD::VPCMPEQWrr t36, t25 However, t36 and t25 are both VR256, while the result type is instead of class VR128. This inconsistency ended up causing the insertion of COPY instructions like this: %vreg7<def> = COPY %vreg3; VR128:%vreg7 VR256:%vreg3 Which is an invalid full copy (not a sub register copy). Eventually, the backend would have hit an UNREACHABLE "Cannot emit physreg copy instruction" in the attempt to expand the malformed pseudo COPY instructions. This patch fixes the problem adding the missing logic in LowerVSETCC to handle the corner case of a setcc with 128-bit return type and 256-bit operand type. This problem was originally reported by Dimitry as PR25080. It has been latent for a very long time. I have added the minimal reproducible from that bugzilla as test setcc-lowering.ll. Differential Revision: http://reviews.llvm.org/D13660 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_37@252484 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 3 years ago
2 changed file(s) with 58 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
1357113571 return DAG.getNode(Opc, dl, VT, Op0, Op1,
1357213572 DAG.getConstant(SSECC, dl, MVT::i8));
1357313573 }
13574
13575 MVT VTOp0 = Op0.getSimpleValueType();
13576 assert(VTOp0 == Op1.getSimpleValueType() &&
13577 "Expected operands with same type!");
13578 assert(VT.getVectorNumElements() == VTOp0.getVectorNumElements() &&
13579 "Invalid number of packed elements for source and destination!");
13580
13581 if (VT.is128BitVector() && VTOp0.is256BitVector()) {
13582 // On non-AVX512 targets, a vector of MVT::i1 is promoted by the type
13583 // legalizer to a wider vector type. In the case of 'vsetcc' nodes, the
13584 // legalizer firstly checks if the first operand in input to the setcc has
13585 // a legal type. If so, then it promotes the return type to that same type.
13586 // Otherwise, the return type is promoted to the 'next legal type' which,
13587 // for a vector of MVT::i1 is always a 128-bit integer vector type.
13588 //
13589 // We reach this code only if the following two conditions are met:
13590 // 1. Both return type and operand type have been promoted to wider types
13591 // by the type legalizer.
13592 // 2. The original operand type has been promoted to a 256-bit vector.
13593 //
13594 // Note that condition 2. only applies for AVX targets.
13595 SDValue NewOp = DAG.getSetCC(dl, VTOp0, Op0, Op1, SetCCOpcode);
13596 return DAG.getZExtOrTrunc(NewOp, dl, VT);
13597 }
13598
13599 // The non-AVX512 code below works under the assumption that source and
13600 // destination types are the same.
13601 assert((Subtarget->hasAVX512() || (VT == VTOp0)) &&
13602 "Value types for source and destination must be the same!");
1357413603
1357513604 // Break 256-bit integer vector compare into smaller ones.
1357613605 if (VT.is256BitVector() && !Subtarget->hasInt256())
0 ; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+avx < %s | FileCheck %s
1
2 ; Verify that we don't crash during codegen due to a wrong lowering
3 ; of a setcc node with illegal operand types and return type.
4
5 define <8 x i16> @pr25080(<8 x i32> %a) {
6 ; CHECK-LABEL: pr25080:
7 ; CHECK: # BB#0: # %entry
8 ; CHECK-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0
9 ; CHECK-NEXT: vextractf128 $1, %ymm0, %xmm1
10 ; CHECK-NEXT: vpxor %xmm2, %xmm2, %xmm2
11 ; CHECK-NEXT: vpcmpeqd %xmm2, %xmm1, %xmm1
12 ; CHECK-NEXT: vmovdqa {{.*#+}} xmm3 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
13 ; CHECK-NEXT: vpshufb %xmm3, %xmm1, %xmm1
14 ; CHECK-NEXT: vpcmpeqd %xmm2, %xmm0, %xmm0
15 ; CHECK-NEXT: vpshufb %xmm3, %xmm0, %xmm0
16 ; CHECK-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
17 ; CHECK-NEXT: vpor {{.*}}(%rip), %xmm0, %xmm0
18 ; CHECK-NEXT: vpsllw $15, %xmm0, %xmm0
19 ; CHECK-NEXT: vpsraw $15, %xmm0, %xmm0
20 ; CHECK-NEXT: vzeroupper
21 ; CHECK-NEXT: retq
22 entry:
23 %0 = trunc <8 x i32> %a to <8 x i23>
24 %1 = icmp eq <8 x i23> %0, zeroinitializer
25 %2 = or <8 x i1> %1,
26 %3 = sext <8 x i1> %2 to <8 x i16>
27 ret <8 x i16> %3
28 }