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.hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode)) {
19 StringRef IEEEAttr = F.getFnAttribute("amdgpu-ieee").getValueAsString();
20 if (!IEEEAttr.empty())
21 IEEE = IEEEAttr == "true";
22
23 StringRef DX10ClampAttr =
24 F.getFnAttribute("amdgpu-dx10-clamp").getValueAsString();
25 if (!DX10ClampAttr.empty())
26 DX10Clamp = DX10ClampAttr == "true";
27 }
28
29 DenormalFPEnv FPEnv = F.getDenormalFPEnv();
31 FP32Denormals = FPEnv.F32Mode;
32}
33
34using namespace AMDGPU;
35
36/// Combine f32 and f64 rounding modes into a combined rounding mode value.
37static constexpr uint32_t getModeRegisterRoundMode(uint32_t HWFP32Val,
38 uint32_t HWFP64Val) {
39 return HWFP32Val << F32FltRoundOffset | HWFP64Val << F64FltRoundOffset;
40}
41
42static constexpr uint64_t encodeFltRoundsTable(uint32_t FltRoundsVal,
43 uint32_t HWF32Val,
44 uint32_t HWF64Val) {
45 uint32_t ModeVal = getModeRegisterRoundMode(HWF32Val, HWF64Val);
46 if (FltRoundsVal > TowardNegative)
47 FltRoundsVal -= ExtendedFltRoundOffset;
48
49 uint32_t BitIndex = ModeVal << 2;
50 return static_cast<uint64_t>(FltRoundsVal) << BitIndex;
51}
52
53// Encode FLT_ROUNDS value where the two rounding modes are the same and use a
54// standard value
55static constexpr uint64_t
57 return encodeFltRoundsTable(FltRoundsMode, HWVal, HWVal);
58}
59
60// Convert mode register encoded rounding mode to AMDGPUFltRounds
61static constexpr AMDGPUFltRounds
63 uint32_t TableRead = (FltRoundConversionTable >> (HWMode << 2)) & 0xf;
64 if (TableRead > TowardNegative)
65 TableRead += ExtendedFltRoundOffset;
66 return static_cast<AMDGPUFltRounds>(TableRead);
67}
68
73
82
89
96
103
105 HWTowardZero) |
110
111// Verify evaluation of FltRoundConversionTable
112
113// If both modes are the same, should return the standard values.
125
135
145
155
165
166// Decode FLT_ROUNDS into the hardware value where the two rounding modes are
167// the same and use a standard value
169 uint32_t FltRoundsVal) {
170 if (FltRoundsVal > TowardNegative)
171 FltRoundsVal -= ExtendedFltRoundOffset;
172
173 return static_cast<uint64_t>(getModeRegisterRoundMode(HWVal, HWVal))
174 << (FltRoundsVal << 2);
175}
176
177/// Decode FLT_ROUNDS into the hardware value where the two rounding modes
178/// different and use an extended value.
180 uint32_t HWF64Val,
181 uint32_t FltRoundsVal) {
182 if (FltRoundsVal > TowardNegative)
183 FltRoundsVal -= ExtendedFltRoundOffset;
184 return static_cast<uint64_t>(getModeRegisterRoundMode(HWF32Val, HWF64Val))
185 << (FltRoundsVal << 2);
186}
187
196
203
210
217
224
225/// Read the hardware rounding mode equivalent of a AMDGPUFltRounds value.
226static constexpr uint32_t
228 uint32_t FltRounds) {
229 uint32_t IndexVal = FltRounds;
230 if (IndexVal > TowardNegative)
231 IndexVal -= ExtendedFltRoundOffset;
232 return (FltRoundToHWConversionTable >> (IndexVal << 2)) & 0xf;
233}
234
236 return ::decodeFltRoundToHWConversionTable(FltRoundToHWConversionTable,
237 FltRounds);
238}
239
240static constexpr uint32_t decodeFltRoundToHW(uint32_t FltRounds) {
241 return ::decodeFltRoundToHWConversionTable(FltRoundToHWConversionTable,
242 FltRounds);
243}
244
245// Verify evaluation of FltRoundToHWConversionTable
246
247static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardZero) ==
249static_assert(decodeFltRoundToHW(AMDGPUFltRounds::NearestTiesToEven) ==
252static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardPositive) ==
254static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardNegative) ==
256
263
270
277
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.