LLVM 23.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 DenormalFPEnv FPEnv = F.getDenormalFPEnv();
33 FP32Denormals = FPEnv.F32Mode;
34}
35
36using namespace AMDGPU;
37
38/// Combine f32 and f64 rounding modes into a combined rounding mode value.
39static constexpr uint32_t getModeRegisterRoundMode(uint32_t HWFP32Val,
40 uint32_t HWFP64Val) {
41 return HWFP32Val << F32FltRoundOffset | HWFP64Val << F64FltRoundOffset;
42}
43
44static constexpr uint64_t encodeFltRoundsTable(uint32_t FltRoundsVal,
45 uint32_t HWF32Val,
46 uint32_t HWF64Val) {
47 uint32_t ModeVal = getModeRegisterRoundMode(HWF32Val, HWF64Val);
48 if (FltRoundsVal > TowardNegative)
49 FltRoundsVal -= ExtendedFltRoundOffset;
50
51 uint32_t BitIndex = ModeVal << 2;
52 return static_cast<uint64_t>(FltRoundsVal) << BitIndex;
53}
54
55// Encode FLT_ROUNDS value where the two rounding modes are the same and use a
56// standard value
57static constexpr uint64_t
59 return encodeFltRoundsTable(FltRoundsMode, HWVal, HWVal);
60}
61
62// Convert mode register encoded rounding mode to AMDGPUFltRounds
63static constexpr AMDGPUFltRounds
65 uint32_t TableRead = (FltRoundConversionTable >> (HWMode << 2)) & 0xf;
66 if (TableRead > TowardNegative)
67 TableRead += ExtendedFltRoundOffset;
68 return static_cast<AMDGPUFltRounds>(TableRead);
69}
70
75
84
91
98
100 HWTowardZero) |
105
107 HWTowardZero) |
112
113// Verify evaluation of FltRoundConversionTable
114
115// If both modes are the same, should return the standard values.
127
137
147
157
167
168// Decode FLT_ROUNDS into the hardware value where the two rounding modes are
169// the same and use a standard value
171 uint32_t FltRoundsVal) {
172 if (FltRoundsVal > TowardNegative)
173 FltRoundsVal -= ExtendedFltRoundOffset;
174
175 return static_cast<uint64_t>(getModeRegisterRoundMode(HWVal, HWVal))
176 << (FltRoundsVal << 2);
177}
178
179/// Decode FLT_ROUNDS into the hardware value where the two rounding modes
180/// different and use an extended value.
182 uint32_t HWF64Val,
183 uint32_t FltRoundsVal) {
184 if (FltRoundsVal > TowardNegative)
185 FltRoundsVal -= ExtendedFltRoundOffset;
186 return static_cast<uint64_t>(getModeRegisterRoundMode(HWF32Val, HWF64Val))
187 << (FltRoundsVal << 2);
188}
189
198
205
212
219
226
227/// Read the hardware rounding mode equivalent of a AMDGPUFltRounds value.
228static constexpr uint32_t
230 uint32_t FltRounds) {
231 uint32_t IndexVal = FltRounds;
232 if (IndexVal > TowardNegative)
233 IndexVal -= ExtendedFltRoundOffset;
234 return (FltRoundToHWConversionTable >> (IndexVal << 2)) & 0xf;
235}
236
238 return ::decodeFltRoundToHWConversionTable(FltRoundToHWConversionTable,
239 FltRounds);
240}
241
242static constexpr uint32_t decodeFltRoundToHW(uint32_t FltRounds) {
243 return ::decodeFltRoundToHWConversionTable(FltRoundToHWConversionTable,
244 FltRounds);
245}
246
247// Verify evaluation of FltRoundToHWConversionTable
248
249static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardZero) ==
251static_assert(decodeFltRoundToHW(AMDGPUFltRounds::NearestTiesToEven) ==
254static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardPositive) ==
256static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardNegative) ==
258
265
272
279
AMD GCN specific subclass of TargetSubtarget.
#define F(x, y, z)
Definition MD5.cpp:54
#define FP_ROUND_ROUND_TO_INF
Definition SIDefines.h:1256
#define FP_ROUND_ROUND_TO_NEAREST
Definition SIDefines.h:1255
#define FP_ROUND_ROUND_TO_ZERO
Definition SIDefines.h:1258
#define FP_ROUND_ROUND_TO_NEGINF
Definition SIDefines.h:1257
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:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
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 Types.h:26
Represents the full denormal controls for a function, including the default mode and the f32 specific...
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.