Skip to content

Commit a4b2c4e

Browse files
committed
Review updates
Use 4-byte spill size in case of no vector support. Build the generic compiler-rt sources for s390x. Don't set libcall names. @llvm.s390.tdc, fcopysign, strict_fminimum/fmaximum. More tests for f16, but not complete. libfuncs built also to double and long double.
1 parent 529c73b commit a4b2c4e

File tree

112 files changed

+2574
-372
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+2574
-372
lines changed

clang/include/clang/Basic/TargetInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ class TargetInfo : public TransferrableTargetInfo,
235235
bool NoAsmVariants; // True if {|} are normal characters.
236236
bool HasLegalHalfType; // True if the backend supports operations on the half
237237
// LLVM IR type.
238-
bool HalfArgsAndReturns;
238+
bool HalfArgsAndReturns; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) type.
239239
bool HasFloat128;
240240
bool HasFloat16;
241241
bool HasBFloat16;

clang/lib/Basic/Targets/SystemZ.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
108108

109109
unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const override;
110110

111-
bool useFP16ConversionIntrinsics() const override {
112-
return false;
113-
}
111+
bool useFP16ConversionIntrinsics() const override { return false; }
114112

115113
void getTargetDefines(const LangOptions &Opts,
116114
MacroBuilder &Builder) const override;

clang/lib/CodeGen/Targets/SystemZ.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class SystemZABIInfo : public ABIInfo {
3131
bool isPromotableIntegerTypeForABI(QualType Ty) const;
3232
bool isCompoundType(QualType Ty) const;
3333
bool isVectorArgumentType(QualType Ty) const;
34-
bool isFPArgumentType(QualType Ty) const;
34+
llvm::Type *getFPArgumentType(QualType Ty, uint64_t Size) const;
3535
QualType GetSingleElementType(QualType Ty) const;
3636

3737
ABIArgInfo classifyReturnType(QualType RetTy) const;
@@ -107,7 +107,8 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
107107
return nullptr;
108108

109109
llvm::Type *Ty = V->getType();
110-
if (Ty->isFloatTy() || Ty->isDoubleTy() || Ty->isFP128Ty()) {
110+
if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy() ||
111+
Ty->isFP128Ty()) {
111112
llvm::Module &M = CGM.getModule();
112113
auto &Ctx = M.getContext();
113114
llvm::Function *TDCFunc = llvm::Intrinsic::getOrInsertDeclaration(
@@ -179,21 +180,31 @@ bool SystemZABIInfo::isVectorArgumentType(QualType Ty) const {
179180
getContext().getTypeSize(Ty) <= 128);
180181
}
181182

182-
bool SystemZABIInfo::isFPArgumentType(QualType Ty) const {
183+
// The Size argument will in case of af an overaligned single element struct
184+
// reflect the overalignment value. In such a case the argument will be
185+
// passed using the type matching Size.
186+
llvm::Type *SystemZABIInfo::getFPArgumentType(QualType Ty,
187+
uint64_t Size) const {
183188
if (IsSoftFloatABI)
184-
return false;
189+
return nullptr;
185190

186191
if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
187192
switch (BT->getKind()) {
188-
case BuiltinType::Float16: // _Float16
193+
case BuiltinType::Float16:
194+
if (Size == 16)
195+
return llvm::Type::getHalfTy(getVMContext());
196+
LLVM_FALLTHROUGH;
189197
case BuiltinType::Float:
198+
if (Size == 32)
199+
return llvm::Type::getFloatTy(getVMContext());
200+
LLVM_FALLTHROUGH;
190201
case BuiltinType::Double:
191-
return true;
202+
return llvm::Type::getDoubleTy(getVMContext());
192203
default:
193-
return false;
204+
return nullptr;
194205
}
195206

196-
return false;
207+
return nullptr;
197208
}
198209

199210
QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
@@ -449,13 +460,11 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
449460
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
450461
/*ByVal=*/false);
451462

452-
// The structure is passed as an unextended integer, a float, or a double.
453-
if (isFPArgumentType(SingleElementTy)) {
463+
// The structure is passed as an unextended integer, a half, a float,
464+
// or a double.
465+
if (llvm::Type *FPArgTy = getFPArgumentType(SingleElementTy, Size)) {
454466
assert(Size == 16 || Size == 32 || Size == 64);
455-
return ABIArgInfo::getDirect(
456-
Size == 16 ? llvm::Type::getHalfTy(getVMContext())
457-
: Size == 32 ? llvm::Type::getFloatTy(getVMContext())
458-
: llvm::Type::getDoubleTy(getVMContext()));
467+
return ABIArgInfo::getDirect(FPArgTy);
459468
} else {
460469
llvm::IntegerType *PassTy = llvm::IntegerType::get(getVMContext(), Size);
461470
return Size <= 32 ? ABIArgInfo::getNoExtend(PassTy)

clang/test/CodeGen/SystemZ/strictfp_builtins.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,24 @@
44

55
#pragma float_control(except, on)
66

7+
// CHECK-LABEL: @test_isnan__Float16(
8+
// CHECK-NEXT: entry:
9+
// CHECK-NEXT: [[F_ADDR:%.*]] = alloca half, align 2
10+
// CHECK-NEXT: store half [[F:%.*]], ptr [[F_ADDR]], align 2
11+
// CHECK-NEXT: [[TMP0:%.*]] = load half, ptr [[F_ADDR]], align 2
12+
// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f16(half [[TMP0]], i64 15) #[[ATTR2:[0-9]+]]
13+
// CHECK-NEXT: ret i32 [[TMP1]]
14+
//
15+
int test_isnan__Float16(_Float16 f) {
16+
return __builtin_isnan(f);
17+
}
18+
719
// CHECK-LABEL: @test_isnan_float(
820
// CHECK-NEXT: entry:
921
// CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4
1022
// CHECK-NEXT: store float [[F:%.*]], ptr [[F_ADDR]], align 4
1123
// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR]], align 4
12-
// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) #[[ATTR2:[0-9]+]]
24+
// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.s390.tdc.f32(float [[TMP0]], i64 15) #[[ATTR2]]
1325
// CHECK-NEXT: ret i32 [[TMP1]]
1426
//
1527
int test_isnan_float(float f) {

clang/test/CodeGen/SystemZ/systemz-abi.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,20 @@ struct agg_longdouble { long double a; };
153153
struct agg_longdouble pass_agg_longdouble(struct agg_longdouble arg) { return arg; }
154154
// CHECK-LABEL: define{{.*}} void @pass_agg_longdouble(ptr dead_on_unwind noalias writable sret(%struct.agg_longdouble) align 8 %{{.*}}, ptr %{{.*}})
155155

156+
struct agg__Float16_a4 { _Float16 a __attribute__((aligned (4))); };
157+
struct agg__Float16_a4 pass_agg__Float16_a4(struct agg__Float16_a4 arg) { return arg; }
158+
// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16_a4(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a4) align 4 %{{.*}}, float %{{.*}})
159+
// SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16_a4(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a4) align 4 %{{.*}}, i32 noext %{{.*}})
160+
156161
struct agg__Float16_a8 { _Float16 a __attribute__((aligned (8))); };
157162
struct agg__Float16_a8 pass_agg__Float16_a8(struct agg__Float16_a8 arg) { return arg; }
158163
// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16_a8(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a8) align 8 %{{.*}}, double %{{.*}})
159164
// SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16_a8(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a8) align 8 %{{.*}}, i64 %{{.*}})
160165

166+
struct agg__Float16_a16 { _Float16 a __attribute__((aligned (16))); };
167+
struct agg__Float16_a16 pass_agg__Float16_a16(struct agg__Float16_a16 arg) { return arg; }
168+
// CHECK-LABEL: define{{.*}} void @pass_agg__Float16_a16(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a16) align 16 %{{.*}}, ptr %{{.*}})
169+
161170
struct agg_float_a8 { float a __attribute__((aligned (8))); };
162171
struct agg_float_a8 pass_agg_float_a8(struct agg_float_a8 arg) { return arg; }
163172
// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg_float_a8(ptr dead_on_unwind noalias writable sret(%struct.agg_float_a8) align 8 %{{.*}}, double %{{.*}})

clang/test/CodeGen/SystemZ/systemz-inline-asm.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ void test_M(void) {
106106
// CHECK: call void asm sideeffect "#FOO $0", "M"(i32 2147483647)
107107
}
108108

109+
_Float16 test_f16(_Float16 a) {
110+
_Float16 f;
111+
asm("ler %0, %1" : "=f" (f) : "f" (a));
112+
return f;
113+
// CHECK-LABEL: define{{.*}} half @test_f16(half noundef %a)
114+
// CHECK: call half asm "ler $0, $1", "=f,f"(half %a)
115+
}
116+
109117
float test_f32(float f, float g) {
110118
asm("aebr %0, %2" : "=f" (f) : "0" (f), "f" (g));
111119
return f;

compiler-rt/cmake/builtin-config-ix.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ set(PPC32 powerpc powerpcspe)
7272
set(PPC64 powerpc64 powerpc64le)
7373
set(RISCV32 riscv32)
7474
set(RISCV64 riscv64)
75+
set(S390X s390x)
7576
set(SPARC sparc)
7677
set(SPARCV9 sparcv9)
7778
set(WASM32 wasm32)
@@ -87,7 +88,7 @@ endif()
8788
set(ALL_BUILTIN_SUPPORTED_ARCH
8889
${X86} ${X86_64} ${AMDGPU} ${ARM32} ${ARM64} ${AVR}
8990
${HEXAGON} ${MIPS32} ${MIPS64} ${NVPTX} ${PPC32} ${PPC64}
90-
${RISCV32} ${RISCV64} ${SPARC} ${SPARCV9}
91+
${RISCV32} ${RISCV64} ${S390X} ${SPARC} ${SPARCV9}
9192
${WASM32} ${WASM64} ${VE} ${LOONGARCH64})
9293

9394
include(CompilerRTUtils)

compiler-rt/lib/builtins/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ set(GENERIC_SOURCES
104104
divti3.c
105105
extendsfdf2.c
106106
extendhfsf2.c
107+
extendhfdf2.c
107108
ffsdi2.c
108109
ffssi2.c
109110
ffsti2.c
@@ -768,6 +769,11 @@ set(riscv64_SOURCES
768769
set(sparc_SOURCES ${GENERIC_SOURCES} ${GENERIC_TF_SOURCES})
769770
set(sparcv9_SOURCES ${GENERIC_SOURCES} ${GENERIC_TF_SOURCES})
770771

772+
set(s390x_SOURCES
773+
${GENERIC_SOURCES}
774+
${GENERIC_TF_SOURCES}
775+
)
776+
771777
set(wasm32_SOURCES
772778
${GENERIC_TF_SOURCES}
773779
${GENERIC_SOURCES}

compiler-rt/lib/builtins/clear_cache.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ void __clear_cache(void *start, void *end) {
6262
#if __i386__ || __x86_64__ || defined(_M_IX86) || defined(_M_X64)
6363
// Intel processors have a unified instruction and data cache
6464
// so there is nothing to do
65+
#elif defined(__s390__)
66+
// no-op
6567
#elif defined(_WIN32) && (defined(__arm__) || defined(__aarch64__))
6668
FlushInstructionCache(GetCurrentProcess(), start, end - start);
6769
#elif defined(__arm__) && !defined(__APPLE__)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===-- lib/extendhfdf2.c - half -> single conversion -------------*- C -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#define SRC_HALF
10+
#define DST_DOUBLE
11+
#include "fp_extend_impl.inc"
12+
13+
// Use a forwarding definition and noinline to implement a poor man's alias,
14+
// as there isn't a good cross-platform way of defining one.
15+
COMPILER_RT_ABI NOINLINE float __extendhfdf2(src_t a) {
16+
return __extendXfYf2__(a);
17+
}
18+
19+
COMPILER_RT_ABI float __gnu_h2d_ieee(src_t a) { return __extendhfdf2(a); }
20+
21+
#if defined(__ARM_EABI__)
22+
#if defined(COMPILER_RT_ARMHF_TARGET)
23+
AEABI_RTABI float __aeabi_h2d(src_t a) { return __extendhfdf2(a); }
24+
#else
25+
COMPILER_RT_ALIAS(__extendhfdf2, __aeabi_h2d)
26+
#endif
27+
#endif

compiler-rt/lib/builtins/extendhftf2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#define QUAD_PRECISION
1111
#include "fp_lib.h"
1212

13-
#if defined(CRT_HAS_TF_MODE) && defined(COMPILER_RT_HAS_FLOAT16)
13+
#if defined(CRT_HAS_TF_MODE)
1414
#define SRC_HALF
1515
#define DST_QUAD
1616
#include "fp_extend_impl.inc"

compiler-rt/lib/builtins/trunctfhf2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#define QUAD_PRECISION
1111
#include "fp_lib.h"
1212

13-
#if defined(CRT_HAS_TF_MODE) && defined(COMPILER_RT_HAS_FLOAT16)
13+
#if defined(CRT_HAS_TF_MODE)
1414
#define SRC_QUAD
1515
#define DST_HALF
1616
#include "fp_trunc_impl.inc"

llvm/docs/LangRef.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5695,7 +5695,7 @@ SystemZ:
56955695
address context evaluates as zero).
56965696
- ``h``: A 32-bit value in the high part of a 64bit data register
56975697
(LLVM-specific)
5698-
- ``f``: A 32, 64, or 128-bit floating-point register.
5698+
- ``f``: A 16, 32, 64, or 128-bit floating-point register.
56995699

57005700
X86:
57015701

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5452,6 +5452,25 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
54525452
DAG.getNode(ISD::FP_ROUND, dl, OVT, Tmp3,
54535453
DAG.getIntPtrConstant(0, dl, /*isTarget=*/true)));
54545454
break;
5455+
5456+
case ISD::STRICT_FMINIMUM: {
5457+
case ISD::STRICT_FMAXIMUM:
5458+
SDValue InChain = Node->getOperand(0);
5459+
SDVTList VTs = DAG.getVTList(NVT, MVT::Other);
5460+
Tmp1 = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, VTs, InChain,
5461+
Node->getOperand(1));
5462+
Tmp2 = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, VTs, InChain,
5463+
Node->getOperand(2));
5464+
SmallVector<SDValue, 4> Ops = {InChain, Tmp1, Tmp2};
5465+
Tmp3 = DAG.getNode(Node->getOpcode(), dl, VTs, Ops, Node->getFlags());
5466+
Tmp4 = DAG.getNode(ISD::STRICT_FP_ROUND, dl, DAG.getVTList(OVT, MVT::Other),
5467+
InChain, Tmp3,
5468+
DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
5469+
Results.push_back(Tmp4);
5470+
Results.push_back(Tmp4.getValue(1));
5471+
break;
5472+
}
5473+
54555474
case ISD::STRICT_FADD:
54565475
case ISD::STRICT_FSUB:
54575476
case ISD::STRICT_FMUL:

llvm/lib/IR/RuntimeLibcalls.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,4 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
253253
}
254254
setLibcallName(RTLIB::MULO_I128, nullptr);
255255
}
256-
257-
if (TT.isSystemZ()) {
258-
setLibcallName(RTLIB::FPROUND_F32_F16, "__truncsfhf2");
259-
setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2");
260-
}
261256
}

llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ ParseStatus SystemZAsmParser::parseRegister(OperandVector &Operands,
901901
return ParseStatus::NoMatch;
902902

903903
// Determine the LLVM register number according to Kind.
904+
// clang-format off
904905
const unsigned *Regs;
905906
switch (Kind) {
906907
case GR32Reg: Regs = SystemZMC::GR32Regs; break;
@@ -918,6 +919,7 @@ ParseStatus SystemZAsmParser::parseRegister(OperandVector &Operands,
918919
case AR32Reg: Regs = SystemZMC::AR32Regs; break;
919920
case CR64Reg: Regs = SystemZMC::CR64Regs; break;
920921
}
922+
// clang-format on
921923
if (Regs[Reg.Num] == 0)
922924
return Error(Reg.StartLoc, "invalid register pair");
923925

llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,10 @@ const unsigned SystemZMC::GR128Regs[16] = {
6565
SystemZ::R8Q, 0, SystemZ::R10Q, 0, SystemZ::R12Q, 0, SystemZ::R14Q, 0};
6666

6767
const unsigned SystemZMC::FP16Regs[16] = {
68-
SystemZ::F0H, SystemZ::F1H, SystemZ::F2H, SystemZ::F3H,
69-
SystemZ::F4H, SystemZ::F5H, SystemZ::F6H, SystemZ::F7H,
70-
SystemZ::F8H, SystemZ::F9H, SystemZ::F10H, SystemZ::F11H,
71-
SystemZ::F12H, SystemZ::F13H, SystemZ::F14H, SystemZ::F15H
72-
};
68+
SystemZ::F0H, SystemZ::F1H, SystemZ::F2H, SystemZ::F3H,
69+
SystemZ::F4H, SystemZ::F5H, SystemZ::F6H, SystemZ::F7H,
70+
SystemZ::F8H, SystemZ::F9H, SystemZ::F10H, SystemZ::F11H,
71+
SystemZ::F12H, SystemZ::F13H, SystemZ::F14H, SystemZ::F15H};
7372

7473
const unsigned SystemZMC::FP32Regs[16] = {
7574
SystemZ::F0S, SystemZ::F1S, SystemZ::F2S, SystemZ::F3S,
@@ -88,15 +87,13 @@ const unsigned SystemZMC::FP128Regs[16] = {
8887
SystemZ::F8Q, SystemZ::F9Q, 0, 0, SystemZ::F12Q, SystemZ::F13Q, 0, 0};
8988

9089
const unsigned SystemZMC::VR16Regs[32] = {
91-
SystemZ::F0H, SystemZ::F1H, SystemZ::F2H, SystemZ::F3H,
92-
SystemZ::F4H, SystemZ::F5H, SystemZ::F6H, SystemZ::F7H,
93-
SystemZ::F8H, SystemZ::F9H, SystemZ::F10H, SystemZ::F11H,
94-
SystemZ::F12H, SystemZ::F13H, SystemZ::F14H, SystemZ::F15H,
95-
SystemZ::F16H, SystemZ::F17H, SystemZ::F18H, SystemZ::F19H,
96-
SystemZ::F20H, SystemZ::F21H, SystemZ::F22H, SystemZ::F23H,
97-
SystemZ::F24H, SystemZ::F25H, SystemZ::F26H, SystemZ::F27H,
98-
SystemZ::F28H, SystemZ::F29H, SystemZ::F30H, SystemZ::F31H
99-
};
90+
SystemZ::F0H, SystemZ::F1H, SystemZ::F2H, SystemZ::F3H, SystemZ::F4H,
91+
SystemZ::F5H, SystemZ::F6H, SystemZ::F7H, SystemZ::F8H, SystemZ::F9H,
92+
SystemZ::F10H, SystemZ::F11H, SystemZ::F12H, SystemZ::F13H, SystemZ::F14H,
93+
SystemZ::F15H, SystemZ::F16H, SystemZ::F17H, SystemZ::F18H, SystemZ::F19H,
94+
SystemZ::F20H, SystemZ::F21H, SystemZ::F22H, SystemZ::F23H, SystemZ::F24H,
95+
SystemZ::F25H, SystemZ::F26H, SystemZ::F27H, SystemZ::F28H, SystemZ::F29H,
96+
SystemZ::F30H, SystemZ::F31H};
10097

10198
const unsigned SystemZMC::VR32Regs[32] = {
10299
SystemZ::F0S, SystemZ::F1S, SystemZ::F2S, SystemZ::F3S, SystemZ::F4S,

0 commit comments

Comments
 (0)