Skip to content

Commit 59f7f35

Browse files
committed
[SystemZ] ABI support for single-element vector types
Support passing and returning values of single-element vector types (i.e. <1 x i128> and <1 x fp128>). Now that i128 is a legal type, supporting these types can be done simply by providing a getRegisterTypeForCallingConv implementation that handles them. Fixes #61291
1 parent 7113c80 commit 59f7f35

17 files changed

+195
-120
lines changed

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,24 +1429,6 @@ bool SystemZTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
14291429
return CI->isTailCall();
14301430
}
14311431

1432-
// We do not yet support 128-bit single-element vector types. If the user
1433-
// attempts to use such types as function argument or return type, prefer
1434-
// to error out instead of emitting code violating the ABI.
1435-
static void VerifyVectorType(MVT VT, EVT ArgVT) {
1436-
if (ArgVT.isVector() && !VT.isVector())
1437-
report_fatal_error("Unsupported vector argument or return type");
1438-
}
1439-
1440-
static void VerifyVectorTypes(const SmallVectorImpl<ISD::InputArg> &Ins) {
1441-
for (unsigned i = 0; i < Ins.size(); ++i)
1442-
VerifyVectorType(Ins[i].VT, Ins[i].ArgVT);
1443-
}
1444-
1445-
static void VerifyVectorTypes(const SmallVectorImpl<ISD::OutputArg> &Outs) {
1446-
for (unsigned i = 0; i < Outs.size(); ++i)
1447-
VerifyVectorType(Outs[i].VT, Outs[i].ArgVT);
1448-
}
1449-
14501432
// Value is a value that has been passed to us in the location described by VA
14511433
// (and so has type VA.getLocVT()). Convert Value to VA.getValVT(), chaining
14521434
// any loads onto Chain.
@@ -1586,10 +1568,6 @@ SDValue SystemZTargetLowering::LowerFormalArguments(
15861568
auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
15871569
EVT PtrVT = getPointerTy(DAG.getDataLayout());
15881570

1589-
// Detect unsupported vector argument types.
1590-
if (Subtarget.hasVector())
1591-
VerifyVectorTypes(Ins);
1592-
15931571
// Assign locations to all of the incoming arguments.
15941572
SmallVector<CCValAssign, 16> ArgLocs;
15951573
SystemZCCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
@@ -1890,12 +1868,6 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI,
18901868
if (Subtarget.isTargetXPLINK64())
18911869
IsTailCall = false;
18921870

1893-
// Detect unsupported vector argument and return types.
1894-
if (Subtarget.hasVector()) {
1895-
VerifyVectorTypes(Outs);
1896-
VerifyVectorTypes(Ins);
1897-
}
1898-
18991871
// Analyze the operands of the call, assigning locations to each operand.
19001872
SmallVector<CCValAssign, 16> ArgLocs;
19011873
SystemZCCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
@@ -2139,10 +2111,6 @@ CanLowerReturn(CallingConv::ID CallConv,
21392111
MachineFunction &MF, bool isVarArg,
21402112
const SmallVectorImpl<ISD::OutputArg> &Outs,
21412113
LLVMContext &Context) const {
2142-
// Detect unsupported vector return types.
2143-
if (Subtarget.hasVector())
2144-
VerifyVectorTypes(Outs);
2145-
21462114
// Special case that we cannot easily detect in RetCC_SystemZ since
21472115
// i128 may not be a legal type.
21482116
for (auto &Out : Outs)
@@ -2162,10 +2130,6 @@ SystemZTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
21622130
const SDLoc &DL, SelectionDAG &DAG) const {
21632131
MachineFunction &MF = DAG.getMachineFunction();
21642132

2165-
// Detect unsupported vector return types.
2166-
if (Subtarget.hasVector())
2167-
VerifyVectorTypes(Outs);
2168-
21692133
// Assign locations to each returned value.
21702134
SmallVector<CCValAssign, 16> RetLocs;
21712135
CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());

llvm/lib/Target/SystemZ/SystemZISelLowering.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,15 @@ class SystemZTargetLowering : public TargetLowering {
443443
return 1;
444444
return TargetLowering::getNumRegisters(Context, VT);
445445
}
446+
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
447+
EVT VT) const override {
448+
// 128-bit single-element vector types are passed like other vectors,
449+
// not like their element type.
450+
if (VT.isVector() && VT.getSizeInBits() == 128 &&
451+
VT.getVectorNumElements() == 1)
452+
return MVT::v16i8;
453+
return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
454+
}
446455
bool isCheapToSpeculateCtlz(Type *) const override { return true; }
447456
bool isCheapToSpeculateCttz(Type *) const override { return true; }
448457
bool preferZeroCompareBranch() const override { return true; }

llvm/test/CodeGen/SystemZ/vec-add-01.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,12 @@ define double @f6(<2 x double> %val1, <2 x double> %val2) {
5858
%ret = fadd double %scalar1, %scalar2
5959
ret double %ret
6060
}
61+
62+
; Test a v1i128 addition.
63+
define <1 x i128> @f7(<1 x i128> %dummy, <1 x i128> %val1, <1 x i128> %val2) {
64+
; CHECK-LABEL: f7:
65+
; CHECK: vaq %v24, %v26, %v28
66+
; CHECK: br %r14
67+
%ret = add <1 x i128> %val1, %val2
68+
ret <1 x i128> %ret
69+
}

llvm/test/CodeGen/SystemZ/vec-add-02.ll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,13 @@ define float @f2(<4 x float> %val1, <4 x float> %val2) {
2222
%ret = fadd float %scalar1, %scalar2
2323
ret float %ret
2424
}
25+
26+
; Test a v1f128 addition.
27+
define <1 x fp128> @f3(<1 x fp128> %dummy, <1 x fp128> %val1,
28+
<1 x fp128> %val2) {
29+
; CHECK-LABEL: f3:
30+
; CHECK: wfaxb %v24, %v26, %v28
31+
; CHECK: br %r14
32+
%ret = fadd <1 x fp128> %val1, %val2
33+
ret <1 x fp128> %ret
34+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2+
; Verify that we handle single-element vector types correctly.
3+
4+
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
5+
6+
define void @f1(<1 x i128> %a, ptr %ptr) {
7+
; CHECK-LABEL: f1:
8+
; CHECK: # %bb.0:
9+
; CHECK-NEXT: vst %v24, 0(%r2), 3
10+
; CHECK-NEXT: br %r14
11+
store <1 x i128> %a, ptr %ptr
12+
ret void
13+
}
14+
15+
define <1 x i128> @f2() {
16+
; CHECK-LABEL: f2:
17+
; CHECK: # %bb.0:
18+
; CHECK-NEXT: vgbm %v24, 0
19+
; CHECK-NEXT: br %r14
20+
ret <1 x i128><i128 0>
21+
}
22+
23+
declare void @bar3(<1 x i128>)
24+
25+
define void @f3() {
26+
; CHECK-LABEL: f3:
27+
; CHECK: # %bb.0:
28+
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
29+
; CHECK-NEXT: .cfi_offset %r14, -48
30+
; CHECK-NEXT: .cfi_offset %r15, -40
31+
; CHECK-NEXT: aghi %r15, -160
32+
; CHECK-NEXT: .cfi_def_cfa_offset 320
33+
; CHECK-NEXT: vgbm %v24, 0
34+
; CHECK-NEXT: brasl %r14, bar3@PLT
35+
; CHECK-NEXT: lmg %r14, %r15, 272(%r15)
36+
; CHECK-NEXT: br %r14
37+
call void @bar3 (<1 x i128> <i128 0>)
38+
ret void
39+
}
40+
41+
declare <1 x i128> @bar4()
42+
43+
define void @f4(ptr %ptr) {
44+
; CHECK-LABEL: f4:
45+
; CHECK: # %bb.0:
46+
; CHECK-NEXT: stmg %r13, %r15, 104(%r15)
47+
; CHECK-NEXT: .cfi_offset %r13, -56
48+
; CHECK-NEXT: .cfi_offset %r14, -48
49+
; CHECK-NEXT: .cfi_offset %r15, -40
50+
; CHECK-NEXT: aghi %r15, -160
51+
; CHECK-NEXT: .cfi_def_cfa_offset 320
52+
; CHECK-NEXT: lgr %r13, %r2
53+
; CHECK-NEXT: brasl %r14, bar4@PLT
54+
; CHECK-NEXT: vst %v24, 0(%r13), 3
55+
; CHECK-NEXT: lmg %r13, %r15, 264(%r15)
56+
; CHECK-NEXT: br %r14
57+
%res = call <1 x i128> @bar4 ()
58+
store <1 x i128> %res, ptr %ptr
59+
ret void
60+
}
61+
62+
define void @f5(<1 x fp128> %a, ptr %ptr) {
63+
; CHECK-LABEL: f5:
64+
; CHECK: # %bb.0:
65+
; CHECK-NEXT: vst %v24, 0(%r2), 3
66+
; CHECK-NEXT: br %r14
67+
store <1 x fp128> %a, ptr %ptr
68+
ret void
69+
}
70+
71+
define <1 x fp128> @f6() {
72+
; CHECK-LABEL: f6:
73+
; CHECK: # %bb.0:
74+
; CHECK-NEXT: lzxr %f0
75+
; CHECK-NEXT: vmrhg %v24, %v0, %v2
76+
; CHECK-NEXT: br %r14
77+
ret <1 x fp128><fp128 0xL00000000000000000000000000000000>
78+
}
79+
80+
declare void @bar7(<1 x fp128>)
81+
82+
define void @f7() {
83+
; CHECK-LABEL: f7:
84+
; CHECK: # %bb.0:
85+
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
86+
; CHECK-NEXT: .cfi_offset %r14, -48
87+
; CHECK-NEXT: .cfi_offset %r15, -40
88+
; CHECK-NEXT: aghi %r15, -160
89+
; CHECK-NEXT: .cfi_def_cfa_offset 320
90+
; CHECK-NEXT: lzxr %f0
91+
; CHECK-NEXT: vmrhg %v24, %v0, %v2
92+
; CHECK-NEXT: brasl %r14, bar7@PLT
93+
; CHECK-NEXT: lmg %r14, %r15, 272(%r15)
94+
; CHECK-NEXT: br %r14
95+
call void @bar7 (<1 x fp128> <fp128 0xL00000000000000000000000000000000>)
96+
ret void
97+
}
98+
99+
declare <1 x fp128> @bar8()
100+
101+
define void @f8(ptr %ptr) {
102+
; CHECK-LABEL: f8:
103+
; CHECK: # %bb.0:
104+
; CHECK-NEXT: stmg %r13, %r15, 104(%r15)
105+
; CHECK-NEXT: .cfi_offset %r13, -56
106+
; CHECK-NEXT: .cfi_offset %r14, -48
107+
; CHECK-NEXT: .cfi_offset %r15, -40
108+
; CHECK-NEXT: aghi %r15, -160
109+
; CHECK-NEXT: .cfi_def_cfa_offset 320
110+
; CHECK-NEXT: lgr %r13, %r2
111+
; CHECK-NEXT: brasl %r14, bar8@PLT
112+
; CHECK-NEXT: vst %v24, 0(%r13), 3
113+
; CHECK-NEXT: lmg %r13, %r15, 264(%r15)
114+
; CHECK-NEXT: br %r14
115+
%res = call <1 x fp128> @bar8 ()
116+
store <1 x fp128> %res, ptr %ptr
117+
ret void
118+
}
119+

llvm/test/CodeGen/SystemZ/vec-args-error-01.ll

Lines changed: 0 additions & 9 deletions
This file was deleted.

llvm/test/CodeGen/SystemZ/vec-args-error-02.ll

Lines changed: 0 additions & 9 deletions
This file was deleted.

llvm/test/CodeGen/SystemZ/vec-args-error-03.ll

Lines changed: 0 additions & 12 deletions
This file was deleted.

llvm/test/CodeGen/SystemZ/vec-args-error-04.ll

Lines changed: 0 additions & 12 deletions
This file was deleted.

llvm/test/CodeGen/SystemZ/vec-args-error-05.ll

Lines changed: 0 additions & 9 deletions
This file was deleted.

llvm/test/CodeGen/SystemZ/vec-args-error-06.ll

Lines changed: 0 additions & 9 deletions
This file was deleted.

llvm/test/CodeGen/SystemZ/vec-args-error-07.ll

Lines changed: 0 additions & 12 deletions
This file was deleted.

llvm/test/CodeGen/SystemZ/vec-args-error-08.ll

Lines changed: 0 additions & 12 deletions
This file was deleted.

llvm/test/CodeGen/SystemZ/vec-strict-add-02.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
66
declare <4 x float> @llvm.experimental.constrained.fadd.v4f32(<4 x float>, <4 x float>, metadata, metadata)
7+
declare <1 x fp128> @llvm.experimental.constrained.fadd.v1f128(<1 x fp128>, <1 x fp128>, metadata, metadata)
78

89
; Test a v4f32 addition.
910
define <4 x float> @f1(<4 x float> %dummy, <4 x float> %val1,
@@ -31,3 +32,17 @@ define float @f2(<4 x float> %val1, <4 x float> %val2) strictfp {
3132
metadata !"fpexcept.strict") strictfp
3233
ret float %ret
3334
}
35+
36+
; Test a v1f128 addition.
37+
define <1 x fp128> @f3(<1 x fp128> %dummy, <1 x fp128> %val1,
38+
<1 x fp128> %val2) strictfp {
39+
; CHECK-LABEL: f3:
40+
; CHECK: wfaxb %v24, %v26, %v28
41+
; CHECK: br %r14
42+
%ret = call <1 x fp128> @llvm.experimental.constrained.fadd.v1f128(
43+
<1 x fp128> %val1, <1 x fp128> %val2,
44+
metadata !"round.dynamic",
45+
metadata !"fpexcept.strict") strictfp
46+
ret <1 x fp128> %ret
47+
}
48+

llvm/test/CodeGen/SystemZ/vec-strict-sub-02.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata)
66
declare <4 x float> @llvm.experimental.constrained.fsub.v4f32(<4 x float>, <4 x float>, metadata, metadata)
7+
declare <1 x fp128> @llvm.experimental.constrained.fsub.v1f128(<1 x fp128>, <1 x fp128>, metadata, metadata)
78

89
; Test a v4f32 subtraction.
910
define <4 x float> @f6(<4 x float> %dummy, <4 x float> %val1,
@@ -32,4 +33,17 @@ define float @f7(<4 x float> %val1, <4 x float> %val2) #0 {
3233
ret float %ret
3334
}
3435

36+
; Test a v1f128 subtraction.
37+
define <1 x fp128> @f8(<1 x fp128> %dummy, <1 x fp128> %val1,
38+
<1 x fp128> %val2) #0 {
39+
; CHECK-LABEL: f8:
40+
; CHECK: wfsxb %v24, %v26, %v28
41+
; CHECK: br %r14
42+
%ret = call <1 x fp128> @llvm.experimental.constrained.fsub.v1f128(
43+
<1 x fp128> %val1, <1 x fp128> %val2,
44+
metadata !"round.dynamic",
45+
metadata !"fpexcept.strict") #0
46+
ret <1 x fp128> %ret
47+
}
48+
3549
attributes #0 = { strictfp }

llvm/test/CodeGen/SystemZ/vec-sub-01.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,12 @@ define <2 x float> @f14(<2 x float> %val1, <2 x float> %val2) {
145145
%ret = fsub <2 x float> %val1, %val2
146146
ret <2 x float> %ret
147147
}
148+
149+
; Test a v1i128 subtraction.
150+
define <1 x i128> @f15(<1 x i128> %dummy, <1 x i128> %val1, <1 x i128> %val2) {
151+
; CHECK-LABEL: f15:
152+
; CHECK: vsq %v24, %v26, %v28
153+
; CHECK: br %r14
154+
%ret = sub <1 x i128> %val1, %val2
155+
ret <1 x i128> %ret
156+
}

0 commit comments

Comments
 (0)