Skip to content

Commit d750cc2

Browse files
committed
[X86][GISel] Fix crash on casting i16 <-> half.
1 parent 3cba379 commit d750cc2

File tree

2 files changed

+83
-3
lines changed

2 files changed

+83
-3
lines changed

llvm/lib/Target/X86/X86InstrInfo.cpp

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4294,10 +4294,28 @@ static unsigned CopyToFromAsymmetricReg(Register DestReg, Register SrcReg,
42944294

42954295
if (X86::VR128XRegClass.contains(DestReg) &&
42964296
X86::GR32RegClass.contains(SrcReg))
4297-
// Copy from a VR128 register to a VR128 register.
4297+
// Copy from a GR32 register to a VR128 register.
42984298
return HasAVX512 ? X86::VMOVDI2PDIZrr
42994299
: HasAVX ? X86::VMOVDI2PDIrr
43004300
: X86::MOVDI2PDIrr;
4301+
4302+
// SrcReg(VR128) -> DestReg(GR16)
4303+
// SrcReg(GR16) -> DestReg(VR128)
4304+
4305+
if (X86::GR16RegClass.contains(DestReg) &&
4306+
X86::VR128XRegClass.contains(SrcReg))
4307+
// Copy from a VR128 register to a GR16 register.
4308+
return HasAVX512 ? X86::VPEXTRWZrri
4309+
: HasAVX ? X86::VPEXTRWrri
4310+
: X86::PEXTRWrri;
4311+
4312+
if (X86::VR128XRegClass.contains(DestReg) &&
4313+
X86::GR16RegClass.contains(SrcReg))
4314+
// Copy from a GR16 register to a VR128 register.
4315+
return HasAVX512 ? X86::VPINSRWZrri
4316+
: HasAVX ? X86::VPINSRWrri
4317+
: X86::PINSRWrri;
4318+
43014319
return 0;
43024320
}
43034321

@@ -4370,8 +4388,24 @@ void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
43704388
Opc = CopyToFromAsymmetricReg(DestReg, SrcReg, Subtarget);
43714389

43724390
if (Opc) {
4373-
BuildMI(MBB, MI, DL, get(Opc), DestReg)
4374-
.addReg(SrcReg, getKillRegState(KillSrc));
4391+
auto MIB = BuildMI(MBB, MI, DL, get(Opc), DestReg);
4392+
switch (Opc) {
4393+
case X86::VPINSRWZrri:
4394+
case X86::VPINSRWrri:
4395+
case X86::PINSRWrri:
4396+
MIB.addReg(DestReg, RegState::Undef)
4397+
.addReg(SrcReg, getKillRegState(KillSrc))
4398+
.addImm(0);
4399+
break;
4400+
case X86::VPEXTRWZrri:
4401+
case X86::VPEXTRWrri:
4402+
case X86::PEXTRWrri:
4403+
MIB.addReg(SrcReg, getKillRegState(KillSrc)).addImm(0);
4404+
break;
4405+
default:
4406+
MIB.addReg(SrcReg, getKillRegState(KillSrc));
4407+
break;
4408+
}
43754409
return;
43764410
}
43774411

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -global-isel | FileCheck %s --check-prefixes=CHECK,SSE2
3+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -global-isel -mattr=+avx | FileCheck %s --check-prefixes=CHECK,AVX
4+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -global-isel -mattr=+avx512f | FileCheck %s --check-prefixes=CHECK,AVX512
5+
6+
define dso_local noundef half @bar(i16 %0) {
7+
; SSE2-LABEL: bar:
8+
; SSE2: # %bb.0: # %entry
9+
; SSE2-NEXT: pinsrw $0, %di, %xmm0
10+
; SSE2-NEXT: retq
11+
;
12+
; AVX-LABEL: bar:
13+
; AVX: # %bb.0: # %entry
14+
; AVX-NEXT: vpinsrw $0, %di, %xmm0, %xmm0
15+
; AVX-NEXT: retq
16+
;
17+
; AVX512-LABEL: bar:
18+
; AVX512: # %bb.0: # %entry
19+
; AVX512-NEXT: vpinsrw $0, %di, %xmm0, %xmm0
20+
; AVX512-NEXT: retq
21+
entry:
22+
%2 = bitcast i16 %0 to half
23+
ret half %2
24+
}
25+
26+
define dso_local noundef i16 @test_half_to_i16(half %0) {
27+
; SSE2-LABEL: test_half_to_i16:
28+
; SSE2: # %bb.0: # %entry
29+
; SSE2-NEXT: pextrw $0, %xmm0, %ax
30+
; SSE2-NEXT: retq
31+
;
32+
; AVX-LABEL: test_half_to_i16:
33+
; AVX: # %bb.0: # %entry
34+
; AVX-NEXT: vpextrw $0, %xmm0, %ax
35+
; AVX-NEXT: retq
36+
;
37+
; AVX512-LABEL: test_half_to_i16:
38+
; AVX512: # %bb.0: # %entry
39+
; AVX512-NEXT: vpextrw $0, %xmm0, %ax
40+
; AVX512-NEXT: retq
41+
entry:
42+
%2 = bitcast half %0 to i16
43+
ret i16 %2
44+
}
45+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
46+
; CHECK: {{.*}}

0 commit comments

Comments
 (0)