Skip to content

Commit 274d1b0

Browse files
authored
[NFC] Add useFPRegsForHalfType(). (#74147)
Currently, half operations can be promoted in one of two ways. * If softPromoteHalfType() returns false, fp16 values are passed around in fp32 registers, and whole chains of fp16 operations are promoted to fp32 in one go. * If softPromoteHalfType() returns true, fp16 values are passed around in i16 registers, and individual fp16 operations are promoted to fp32 and the result truncated to fp16 right away. The softPromoteHalfType behavior is necessary for correctness, but changing this for an existing target breaks the ABI. Therefore, this commit adds a third option: * If softPromoteHalfType() returns true and useFPRegsForHalfType() returns true as well, fp16 values are passed around in fp32 registers, but individual fp16 operations are promoted to fp32 and the result truncated to fp16 right away. This change does not yet update any target to make use of it.
1 parent 1f4a5d8 commit 274d1b0

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

+10-4
Original file line numberDiff line numberDiff line change
@@ -505,12 +505,18 @@ class TargetLoweringBase {
505505
return TypePromoteInteger;
506506
}
507507

508-
// Return true if the half type should be passed around as i16, but promoted
509-
// to float around arithmetic. The default behavior is to pass around as
510-
// float and convert around loads/stores/bitcasts and other places where
511-
// the size matters.
508+
// Return true if the half type should be promoted using soft promotion rules
509+
// where each operation is promoted to f32 individually, then converted to
510+
// fp16. The default behavior is to promote chains of operations, keeping
511+
// intermediate results in f32 precision and range.
512512
virtual bool softPromoteHalfType() const { return false; }
513513

514+
// Return true if, for soft-promoted half, the half type should be passed
515+
// passed to and returned from functions as f32. The default behavior is to
516+
// pass as i16. If soft-promoted half is not used, this function is ignored
517+
// and values are always passed and returned as f32.
518+
virtual bool useFPRegsForHalfType() const { return false; }
519+
514520
// There are two general methods for expanding a BUILD_VECTOR node:
515521
// 1. Use SCALAR_TO_VECTOR on the defined scalar values and then shuffle
516522
// them together.

llvm/lib/CodeGen/TargetLoweringBase.cpp

+9-4
Original file line numberDiff line numberDiff line change
@@ -1430,15 +1430,20 @@ void TargetLoweringBase::computeRegisterProperties(
14301430
// conversions).
14311431
if (!isTypeLegal(MVT::f16)) {
14321432
// Allow targets to control how we legalize half.
1433-
if (softPromoteHalfType()) {
1433+
bool SoftPromoteHalfType = softPromoteHalfType();
1434+
bool UseFPRegsForHalfType = !SoftPromoteHalfType || useFPRegsForHalfType();
1435+
1436+
if (!UseFPRegsForHalfType) {
14341437
NumRegistersForVT[MVT::f16] = NumRegistersForVT[MVT::i16];
14351438
RegisterTypeForVT[MVT::f16] = RegisterTypeForVT[MVT::i16];
1436-
TransformToType[MVT::f16] = MVT::f32;
1437-
ValueTypeActions.setTypeAction(MVT::f16, TypeSoftPromoteHalf);
14381439
} else {
14391440
NumRegistersForVT[MVT::f16] = NumRegistersForVT[MVT::f32];
14401441
RegisterTypeForVT[MVT::f16] = RegisterTypeForVT[MVT::f32];
1441-
TransformToType[MVT::f16] = MVT::f32;
1442+
}
1443+
TransformToType[MVT::f16] = MVT::f32;
1444+
if (SoftPromoteHalfType) {
1445+
ValueTypeActions.setTypeAction(MVT::f16, TypeSoftPromoteHalf);
1446+
} else {
14421447
ValueTypeActions.setTypeAction(MVT::f16, TypePromoteFloat);
14431448
}
14441449
}

0 commit comments

Comments
 (0)