LLVM 19.0.0git
SIModeRegisterDefaults.cpp
Go to the documentation of this file.
1//===-- SIModeRegisterDefaults.cpp ------------------------------*- 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
10#include "GCNSubtarget.h"
11
12using namespace llvm;
13
15 const GCNSubtarget &ST) {
16 *this = getDefaultForCallingConv(F.getCallingConv());
17
18 if (ST.hasIEEEMode()) {
19 StringRef IEEEAttr = F.getFnAttribute("amdgpu-ieee").getValueAsString();
20 if (!IEEEAttr.empty())
21 IEEE = IEEEAttr == "true";
22 }
23
24 if (ST.hasDX10ClampMode()) {
25 StringRef DX10ClampAttr =
26 F.getFnAttribute("amdgpu-dx10-clamp").getValueAsString();
27 if (!DX10ClampAttr.empty())
28 DX10Clamp = DX10ClampAttr == "true";
29 }
30
31 StringRef DenormF32Attr =
32 F.getFnAttribute("denormal-fp-math-f32").getValueAsString();
33 if (!DenormF32Attr.empty())
35
36 StringRef DenormAttr =
37 F.getFnAttribute("denormal-fp-math").getValueAsString();
38 if (!DenormAttr.empty()) {
39 DenormalMode DenormMode = parseDenormalFPAttribute(DenormAttr);
40 if (DenormF32Attr.empty())
41 FP32Denormals = DenormMode;
42 FP64FP16Denormals = DenormMode;
43 }
44}
45
46using namespace AMDGPU;
47
48/// Combine f32 and f64 rounding modes into a combined rounding mode value.
49static constexpr uint32_t getModeRegisterRoundMode(uint32_t HWFP32Val,
50 uint32_t HWFP64Val) {
51 return HWFP32Val << F32FltRoundOffset | HWFP64Val << F64FltRoundOffset;
52}
53
54static constexpr uint64_t encodeFltRoundsTable(uint32_t FltRoundsVal,
55 uint32_t HWF32Val,
56 uint32_t HWF64Val) {
57 uint32_t ModeVal = getModeRegisterRoundMode(HWF32Val, HWF64Val);
58 if (FltRoundsVal > TowardNegative)
59 FltRoundsVal -= ExtendedFltRoundOffset;
60
61 uint32_t BitIndex = ModeVal << 2;
62 return static_cast<uint64_t>(FltRoundsVal) << BitIndex;
63}
64
65// Encode FLT_ROUNDS value where the two rounding modes are the same and use a
66// standard value
67static constexpr uint64_t
69 return encodeFltRoundsTable(FltRoundsMode, HWVal, HWVal);
70}
71
72// Convert mode register encoded rounding mode to AMDGPUFltRounds
73static constexpr AMDGPUFltRounds
75 uint32_t TableRead = (FltRoundConversionTable >> (HWMode << 2)) & 0xf;
76 if (TableRead > TowardNegative)
77 TableRead += ExtendedFltRoundOffset;
78 return static_cast<AMDGPUFltRounds>(TableRead);
79}
80
85
94
101
108
110 HWTowardZero) |
115
117 HWTowardZero) |
122
123// Verify evaluation of FltRoundConversionTable
124
125// If both modes are the same, should return the standard values.
127 HWTowardZero, HWTowardZero)) == AMDGPUFltRounds::TowardZero);
130 AMDGPUFltRounds::NearestTiesToEven);
133 AMDGPUFltRounds::TowardPositive);
136 AMDGPUFltRounds::TowardNegative);
137
147
157
167
177
178// Decode FLT_ROUNDS into the hardware value where the two rounding modes are
179// the same and use a standard value
181 uint32_t FltRoundsVal) {
182 if (FltRoundsVal > TowardNegative)
183 FltRoundsVal -= ExtendedFltRoundOffset;
184
185 return static_cast<uint64_t>(getModeRegisterRoundMode(HWVal, HWVal))
186 << (FltRoundsVal << 2);
187}
188
189/// Decode FLT_ROUNDS into the hardware value where the two rounding modes
190/// different and use an extended value.
192 uint32_t HWF64Val,
193 uint32_t FltRoundsVal) {
194 if (FltRoundsVal > TowardNegative)
195 FltRoundsVal -= ExtendedFltRoundOffset;
196 return static_cast<uint64_t>(getModeRegisterRoundMode(HWF32Val, HWF64Val))
197 << (FltRoundsVal << 2);
198}
199
208
215
222
229
236
237/// Read the hardware rounding mode equivalent of a AMDGPUFltRounds value.
238static constexpr uint32_t
240 uint32_t FltRounds) {
241 uint32_t IndexVal = FltRounds;
242 if (IndexVal > TowardNegative)
243 IndexVal -= ExtendedFltRoundOffset;
244 return (FltRoundToHWConversionTable >> (IndexVal << 2)) & 0xf;
245}
246
248 return ::decodeFltRoundToHWConversionTable(FltRoundToHWConversionTable,
249 FltRounds);
250}
251
252static constexpr uint32_t decodeFltRoundToHW(uint32_t FltRounds) {
253 return ::decodeFltRoundToHWConversionTable(FltRoundToHWConversionTable,
254 FltRounds);
255}
256
257// Verify evaluation of FltRoundToHWConversionTable
258
259static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardZero) ==
261static_assert(decodeFltRoundToHW(AMDGPUFltRounds::NearestTiesToEven) ==
264static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardPositive) ==
266static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardNegative) ==
268
275
282
289
AMD GCN specific subclass of TargetSubtarget.
#define F(x, y, z)
Definition: MD5.cpp:55
#define FP_ROUND_ROUND_TO_INF
Definition: SIDefines.h:1159
#define FP_ROUND_ROUND_TO_NEAREST
Definition: SIDefines.h:1158
#define FP_ROUND_ROUND_TO_ZERO
Definition: SIDefines.h:1161
#define FP_ROUND_ROUND_TO_NEGINF
Definition: SIDefines.h:1160
static constexpr uint64_t encodeFltRoundsToHWTable(uint32_t HWF32Val, uint32_t HWF64Val, uint32_t FltRoundsVal)
Decode FLT_ROUNDS into the hardware value where the two rounding modes different and use an extended ...
static constexpr uint32_t decodeFltRoundToHW(uint32_t FltRounds)
static constexpr AMDGPUFltRounds decodeIndexFltRoundConversionTable(uint32_t HWMode)
static constexpr uint32_t HWTowardNegative
static constexpr uint64_t encodeFltRoundsTableSame(AMDGPUFltRounds FltRoundsMode, uint32_t HWVal)
static constexpr uint32_t HWTowardPositive
static constexpr uint32_t HWTowardZero
static constexpr uint64_t encodeFltRoundsToHWTableSame(uint32_t HWVal, uint32_t FltRoundsVal)
static constexpr uint64_t encodeFltRoundsTable(uint32_t FltRoundsVal, uint32_t HWF32Val, uint32_t HWF64Val)
static constexpr uint32_t decodeFltRoundToHWConversionTable(uint64_t FltRoundToHWConversionTable, uint32_t FltRounds)
Read the hardware rounding mode equivalent of a AMDGPUFltRounds value.
static constexpr uint32_t HWNearestTiesToEven
static constexpr uint32_t getModeRegisterRoundMode(uint32_t HWFP32Val, uint32_t HWFP64Val)
Combine f32 and f64 rounding modes into a combined rounding mode value.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
const uint64_t FltRoundToHWConversionTable
static constexpr uint32_t F64FltRoundOffset
Offset in mode register of f64/f16 rounding mode.
static constexpr uint32_t ExtendedFltRoundOffset
Offset of nonstandard values for llvm.get.rounding results from the largest supported mode.
AMDGPUFltRounds
Return values used for llvm.get.rounding.
uint32_t decodeFltRoundToHWConversionTable(uint32_t FltRounds)
Read the hardware rounding mode equivalent of a AMDGPUFltRounds value.
static constexpr uint32_t F32FltRoundOffset
Offset in mode register of f32 rounding mode.
const uint64_t FltRoundConversionTable
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ TowardNegative
roundTowardNegative.
DenormalMode parseDenormalFPAttribute(StringRef Str)
Returns the denormal mode to use for inputs and outputs.
Represent subnormal handling kind for floating point instruction inputs and outputs.
bool DX10Clamp
Used by the vector ALU to force DX10-style treatment of NaNs: when set, clamp NaN to zero; otherwise,...
DenormalMode FP64FP16Denormals
If this is set, neither input or output denormals are flushed for both f64 and f16/v2f16 instructions...
bool IEEE
Floating point opcodes that support exception flag gathering quiet and propagate signaling NaN inputs...
static SIModeRegisterDefaults getDefaultForCallingConv(CallingConv::ID CC)
DenormalMode FP32Denormals
If this is set, neither input or output denormals are flushed for most f32 instructions.