Skip to content

Commit 29fff07

Browse files
committed
[X86] Improve the type checking fast-isel handling of vector bitcasts.
We had a bunch of vector size legality checks for the source type based on feature flags, but we didn't check the destination type at all beyond ensuring that it was a "simple" type. But this allowed the destination to be i128 which isn't legal. This commit changes the code to use TLI's isTypeLegal logic in place of the all the subtarget checks. Then additionally checks that the source and dest are vectors. Fixes 42452 llvm-svn: 364729
1 parent 4ca81a9 commit 29fff07

File tree

2 files changed

+45
-13
lines changed

2 files changed

+45
-13
lines changed

llvm/lib/Target/X86/X86FastISel.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3646,24 +3646,19 @@ X86FastISel::fastSelectInstruction(const Instruction *I) {
36463646
return true;
36473647
}
36483648
case Instruction::BitCast: {
3649-
// Select SSE2/AVX bitcasts between 128/256 bit vector types.
3649+
// Select SSE2/AVX bitcasts between 128/256/512 bit vector types.
36503650
if (!Subtarget->hasSSE2())
36513651
return false;
36523652

3653-
EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType());
3654-
EVT DstVT = TLI.getValueType(DL, I->getType());
3655-
3656-
if (!SrcVT.isSimple() || !DstVT.isSimple())
3653+
MVT SrcVT, DstVT;
3654+
if (!isTypeLegal(I->getOperand(0)->getType(), SrcVT) ||
3655+
!isTypeLegal(I->getType(), DstVT))
36573656
return false;
36583657

3659-
MVT SVT = SrcVT.getSimpleVT();
3660-
MVT DVT = DstVT.getSimpleVT();
3661-
3662-
if (!SVT.is128BitVector() &&
3663-
!(Subtarget->hasAVX() && SVT.is256BitVector()) &&
3664-
!(Subtarget->hasAVX512() && SVT.is512BitVector() &&
3665-
(Subtarget->hasBWI() || (SVT.getScalarSizeInBits() >= 32 &&
3666-
DVT.getScalarSizeInBits() >= 32))))
3658+
// Only allow vectors that use xmm/ymm/zmm.
3659+
if (!SrcVT.isVector() || !DstVT.isVector() ||
3660+
SrcVT.getVectorElementType() == MVT::i1 ||
3661+
DstVT.getVectorElementType() == MVT::i1)
36673662
return false;
36683663

36693664
unsigned Reg = getRegForValue(I->getOperand(0));

llvm/test/CodeGen/X86/pr42452.ll

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -O0 | FileCheck %s
3+
4+
@b = external global i64, align 8
5+
6+
define void @foo(i1 %c, <2 x i64> %x) {
7+
; CHECK-LABEL: foo:
8+
; CHECK: # %bb.0: # %entry
9+
; CHECK-NEXT: # kill: def $dil killed $dil killed $edi
10+
; CHECK-NEXT: movq %xmm0, %rax
11+
; CHECK-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
12+
; CHECK-NEXT: movq %xmm0, %rcx
13+
; CHECK-NEXT: movb %dil, {{[-0-9]+}}(%r{{[sb]}}p) # 1-byte Spill
14+
; CHECK-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
15+
; CHECK-NEXT: .LBB0_1: # %for.body
16+
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
17+
; CHECK-NEXT: movb {{[-0-9]+}}(%r{{[sb]}}p), %al # 1-byte Reload
18+
; CHECK-NEXT: testb $1, %al
19+
; CHECK-NEXT: jne .LBB0_1
20+
; CHECK-NEXT: jmp .LBB0_2
21+
; CHECK-NEXT: .LBB0_2: # %for.end
22+
; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
23+
; CHECK-NEXT: movq %rax, b
24+
; CHECK-NEXT: retq
25+
entry:
26+
%0 = bitcast <2 x i64> %x to i128
27+
br label %for.body
28+
29+
for.body: ; preds = %for.body, %entry
30+
br i1 %c, label %for.body, label %for.end
31+
32+
for.end: ; preds = %for.body
33+
%1 = lshr i128 %0, 64
34+
%2 = trunc i128 %1 to i64
35+
store i64 %2, i64* @b, align 8
36+
ret void
37+
}

0 commit comments

Comments
 (0)