Skip to content

Commit 47a377d

Browse files
committed
[SPIRV] Fix OpConstant float and double printing
Print OpConstant floats as formatted decimal floating points, with special case exceptions to print infinity and NaN as hexfloats. This change follows from the fixes in #66686 to correct how constant values are printed generally. Differential Revision: https://reviews.llvm.org/D159376
1 parent 2ed813f commit 47a377d

File tree

4 files changed

+79
-7
lines changed

4 files changed

+79
-7
lines changed

llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "SPIRVInstPrinter.h"
1414
#include "SPIRV.h"
1515
#include "SPIRVBaseInfo.h"
16+
#include "llvm/ADT/APFloat.h"
1617
#include "llvm/CodeGen/Register.h"
1718
#include "llvm/MC/MCAsmInfo.h"
1819
#include "llvm/MC/MCExpr.h"
@@ -49,14 +50,49 @@ void SPIRVInstPrinter::printRemainingVariableOps(const MCInst *MI,
4950
void SPIRVInstPrinter::printOpConstantVarOps(const MCInst *MI,
5051
unsigned StartIndex,
5152
raw_ostream &O) {
53+
const unsigned NumVarOps = MI->getNumOperands() - StartIndex;
54+
55+
assert((NumVarOps == 1 || NumVarOps == 2) &&
56+
"Unsupported number of bits for literal variable");
57+
5258
O << ' ';
53-
if (MI->getNumOperands() - StartIndex == 2) { // Handle 64 bit literals.
54-
uint64_t Imm = MI->getOperand(StartIndex).getImm();
59+
60+
uint64_t Imm = MI->getOperand(StartIndex).getImm();
61+
62+
// Handle 64 bit literals.
63+
if (NumVarOps == 2) {
5564
Imm |= (MI->getOperand(StartIndex + 1).getImm() << 32);
56-
O << Imm;
57-
} else {
58-
printRemainingVariableOps(MI, StartIndex, O, true, false);
5965
}
66+
67+
// Format and print float values.
68+
if (MI->getOpcode() == SPIRV::OpConstantF) {
69+
APFloat FP = NumVarOps == 1 ? APFloat(APInt(32, Imm).bitsToFloat())
70+
: APFloat(APInt(64, Imm).bitsToDouble());
71+
72+
// Print infinity and NaN as hex floats.
73+
// TODO: Make sure subnormal numbers are handled correctly as they may also
74+
// require hex float notation.
75+
if (FP.isInfinity()) {
76+
if (FP.isNegative())
77+
O << '-';
78+
O << "0x1p+128";
79+
return;
80+
}
81+
if (FP.isNaN()) {
82+
O << "0x1.8p+128";
83+
return;
84+
}
85+
86+
// Format val as a decimal floating point or scientific notation (whichever
87+
// is shorter), with enough digits of precision to produce the exact value.
88+
O << format("%.*g", std::numeric_limits<double>::max_digits10,
89+
FP.convertToDouble());
90+
91+
return;
92+
}
93+
94+
// Print integer values directly.
95+
O << Imm;
6096
}
6197

6298
void SPIRVInstPrinter::recordOpExtInstImport(const MCInst *MI) {

llvm/test/CodeGen/SPIRV/AtomicBuiltinsFloat.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
;; Types:
44
; CHECK: %[[#F32:]] = OpTypeFloat 32
55
;; Constants:
6-
; CHECK: %[[#CONST:]] = OpConstant %[[#F32]] 1065353216
6+
; CHECK: %[[#CONST:]] = OpConstant %[[#F32]] 1
77
;; Atomic instructions:
88
; CHECK: OpStore %[[#]] %[[#CONST]]
99
; CHECK-COUNT-3: OpAtomicStore

llvm/test/CodeGen/SPIRV/atomicrmw.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
; CHECK-DAG: %[[#FPPointerType:]] = OpTypePointer CrossWorkgroup %[[#Float]]
1414
; CHECK-DAG: %[[#Pointer:]] = OpVariable %[[#PointerType]] CrossWorkgroup
1515
; CHECK-DAG: %[[#FPPointer:]] = OpVariable %[[#FPPointerType]] CrossWorkgroup
16-
; CHECK-DAG: %[[#FPValue:]] = OpConstant %[[#Float]] 1109917696
16+
; CHECK-DAG: %[[#FPValue:]] = OpConstant %[[#Float]] 42
1717

1818
@ui = common dso_local addrspace(1) global i32 0, align 4
1919
@f = common dso_local local_unnamed_addr addrspace(1) global float 0.000000e+00, align 4

llvm/test/CodeGen/SPIRV/literals.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
3+
; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
4+
5+
; CHECK: %[[#F32:]] = OpTypeFloat 32
6+
; CHECK: %[[#F64:]] = OpTypeFloat 64
7+
8+
define void @main() {
9+
entry:
10+
11+
; CHECK: OpConstant %[[#F32]] 0.5
12+
%f = alloca float, align 4
13+
store float 5.000000e-01, ptr %f, align 4
14+
15+
; CHECK: OpConstant %[[#F64]] 0.5
16+
%d = alloca double, align 8
17+
store double 5.000000e-01, ptr %d, align 8
18+
19+
; CHECK: OpConstant %[[#F32]] 1.0000016166037976e-39
20+
%hexf = alloca float, align 4
21+
store float 0x37D5C73200000000, ptr %hexf, align 4
22+
23+
; CHECK: OpConstant %[[#F32]] 0x1p+128
24+
%inf = alloca float, align 4
25+
store float 0x7FF0000000000000, ptr %inf, align 4
26+
27+
; CHECK: OpConstant %[[#F32]] -0x1p+128
28+
%ninf = alloca float, align 4
29+
store float 0xFFF0000000000000, ptr %ninf, align 4
30+
31+
; CHECK: OpConstant %[[#F32]] 0x1.8p+128
32+
%nan = alloca float, align 4
33+
store float 0x7FF8000000000000, ptr %nan, align 4
34+
35+
ret void
36+
}

0 commit comments

Comments
 (0)