Skip to content

Commit 1ab6632

Browse files
committed
[PATCH][SPIRV] Add no signed/unsigned wrap decoration support
1 parent e54a274 commit 1ab6632

File tree

1 file changed

+203
-0
lines changed

1 file changed

+203
-0
lines changed
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
From c6601b20b40b6b1de8d5472b043f2f69a6626eab Mon Sep 17 00:00:00 2001
2+
From: Mariya Podchishchaeva <[email protected]>
3+
Date: Wed, 26 Dec 2018 20:17:38 +0300
4+
Subject: [PATCH] Add no signed/unsigned wrap decoration support
5+
6+
---
7+
lib/SPIRV/SPIRVReader.cpp | 9 +++++++++
8+
lib/SPIRV/SPIRVRegularizeLLVM.cpp | 6 ------
9+
lib/SPIRV/SPIRVWriter.cpp | 10 +++++++++
10+
lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h | 2 ++
11+
lib/SPIRV/libSPIRV/SPIRVValue.cpp | 28 ++++++++++++++++++++++++++
12+
lib/SPIRV/libSPIRV/SPIRVValue.h | 4 ++++
13+
lib/SPIRV/libSPIRV/spirv.hpp | 2 ++
14+
test/NoSignedUnsignedWrap.ll | 38 +++++++++++++++++++++++++++++++++++
15+
8 files changed, 93 insertions(+), 6 deletions(-)
16+
create mode 100644 test/NoSignedUnsignedWrap.ll
17+
18+
diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp
19+
index 717b3a7..d83405a 100644
20+
--- a/lib/SPIRV/SPIRVReader.cpp
21+
+++ b/lib/SPIRV/SPIRVReader.cpp
22+
@@ -694,6 +694,15 @@ BinaryOperator *SPIRVToLLVM::transShiftLogicalBitwiseInst(SPIRVValue *BV,
23+
auto Inst = BinaryOperator::Create(BO, transValue(BBN->getOperand(0), F, BB),
24+
transValue(BBN->getOperand(1), F, BB),
25+
BV->getName(), BB);
26+
+
27+
+ if (BV->hasDecorate(DecorationNoSignedWrap)) {
28+
+ Inst->setHasNoSignedWrap(true);
29+
+ }
30+
+
31+
+ if (BV->hasDecorate(DecorationNoUnsignedWrap)) {
32+
+ Inst->setHasNoUnsignedWrap(true);
33+
+ }
34+
+
35+
return Inst;
36+
}
37+
38+
diff --git a/lib/SPIRV/SPIRVRegularizeLLVM.cpp b/lib/SPIRV/SPIRVRegularizeLLVM.cpp
39+
index 4a1837d..84f7492 100644
40+
--- a/lib/SPIRV/SPIRVRegularizeLLVM.cpp
41+
+++ b/lib/SPIRV/SPIRVRegularizeLLVM.cpp
42+
@@ -132,12 +132,6 @@ bool SPIRVRegularizeLLVM::regularize() {
43+
44+
// Remove optimization info not supported by SPIRV
45+
if (auto BO = dyn_cast<BinaryOperator>(II)) {
46+
- if (isa<OverflowingBinaryOperator>(BO)) {
47+
- if (BO->hasNoUnsignedWrap())
48+
- BO->setHasNoUnsignedWrap(false);
49+
- if (BO->hasNoSignedWrap())
50+
- BO->setHasNoSignedWrap(false);
51+
- }
52+
if (isa<PossiblyExactOperator>(BO) && BO->isExact())
53+
BO->setIsExact(false);
54+
}
55+
diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp
56+
index 158ef4d..fdba9d9 100644
57+
--- a/lib/SPIRV/SPIRVWriter.cpp
58+
+++ b/lib/SPIRV/SPIRVWriter.cpp
59+
@@ -1023,6 +1023,16 @@ bool LLVMToSPIRV::transDecoration(Value *V, SPIRVValue *BV) {
60+
if ((isa<AtomicCmpXchgInst>(V) && cast<AtomicCmpXchgInst>(V)->isVolatile()) ||
61+
(isa<AtomicRMWInst>(V) && cast<AtomicRMWInst>(V)->isVolatile()))
62+
BV->setVolatile(true);
63+
+
64+
+ if (auto BVO = dyn_cast_or_null<OverflowingBinaryOperator>(V)) {
65+
+ if (BVO->hasNoSignedWrap()) {
66+
+ BV->setNoSignedWrap(true);
67+
+ }
68+
+ if (BVO->hasNoUnsignedWrap()) {
69+
+ BV->setNoUnsignedWrap(true);
70+
+ }
71+
+ }
72+
+
73+
return true;
74+
}
75+
76+
diff --git a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h
77+
index 409d49b..1ef7901 100644
78+
--- a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h
79+
+++ b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h
80+
@@ -329,6 +329,8 @@ template <> inline void SPIRVMap<Decoration, std::string>::init() {
81+
add(DecorationInputAttachmentIndex, "InputAttachmentIndex");
82+
add(DecorationAlignment, "Alignment");
83+
add(DecorationMaxByteOffset, "MaxByteOffset");
84+
+ add(DecorationNoSignedWrap, "NoSignedWrap");
85+
+ add(DecorationNoUnsignedWrap, "NoUnsignedWrap");
86+
}
87+
SPIRV_DEF_NAMEMAP(Decoration, SPIRVDecorationNameMap)
88+
89+
diff --git a/lib/SPIRV/libSPIRV/SPIRVValue.cpp b/lib/SPIRV/libSPIRV/SPIRVValue.cpp
90+
index fadd474..d5591ca 100644
91+
--- a/lib/SPIRV/libSPIRV/SPIRVValue.cpp
92+
+++ b/lib/SPIRV/libSPIRV/SPIRVValue.cpp
93+
@@ -68,4 +68,32 @@ void SPIRVValue::setVolatile(bool IsVolatile) {
94+
<< " for obj " << Id << "\n")
95+
}
96+
97+
+bool SPIRVValue::hasNoSignedWrap() const {
98+
+ return hasDecorate(DecorationNoSignedWrap);
99+
+}
100+
+
101+
+void SPIRVValue::setNoSignedWrap(bool HasNoSignedWrap) {
102+
+ if (!HasNoSignedWrap) {
103+
+ eraseDecorate(DecorationNoSignedWrap);
104+
+ return;
105+
+ }
106+
+ addDecorate(new SPIRVDecorate(DecorationNoSignedWrap, this));
107+
+ SPIRVDBG(spvdbgs() << "Set nsw "
108+
+ << " for obj " << Id << "\n")
109+
+}
110+
+
111+
+bool SPIRVValue::hasNoUnsignedWrap() const {
112+
+ return hasDecorate(DecorationNoUnsignedWrap);
113+
+}
114+
+
115+
+void SPIRVValue::setNoUnsignedWrap(bool HasNoUnsignedWrap) {
116+
+ if (!HasNoUnsignedWrap) {
117+
+ eraseDecorate(DecorationNoUnsignedWrap);
118+
+ return;
119+
+ }
120+
+ addDecorate(new SPIRVDecorate(DecorationNoUnsignedWrap, this));
121+
+ SPIRVDBG(spvdbgs() << "Set nuw "
122+
+ << " for obj " << Id << "\n")
123+
+}
124+
+
125+
} // namespace SPIRV
126+
diff --git a/lib/SPIRV/libSPIRV/SPIRVValue.h b/lib/SPIRV/libSPIRV/SPIRVValue.h
127+
index 8d58fce..3a7f75d 100644
128+
--- a/lib/SPIRV/libSPIRV/SPIRVValue.h
129+
+++ b/lib/SPIRV/libSPIRV/SPIRVValue.h
130+
@@ -91,9 +91,13 @@ public:
131+
}
132+
bool isVolatile() const;
133+
bool hasAlignment(SPIRVWord *Result = 0) const;
134+
+ bool hasNoSignedWrap() const;
135+
+ bool hasNoUnsignedWrap() const;
136+
137+
void setAlignment(SPIRVWord);
138+
void setVolatile(bool IsVolatile);
139+
+ void setNoSignedWrap(bool HasNoSignedWrap);
140+
+ void setNoUnsignedWrap(bool HasNoUnsignedWrap);
141+
142+
void validate() const override {
143+
SPIRVEntry::validate();
144+
diff --git a/lib/SPIRV/libSPIRV/spirv.hpp b/lib/SPIRV/libSPIRV/spirv.hpp
145+
index e8536d3..cfdbeb2 100644
146+
--- a/lib/SPIRV/libSPIRV/spirv.hpp
147+
+++ b/lib/SPIRV/libSPIRV/spirv.hpp
148+
@@ -382,6 +382,8 @@ enum Decoration {
149+
DecorationInputAttachmentIndex = 43,
150+
DecorationAlignment = 44,
151+
DecorationMaxByteOffset = 45,
152+
+ DecorationNoSignedWrap = 4469,
153+
+ DecorationNoUnsignedWrap = 4470,
154+
DecorationOverrideCoverageNV = 5248,
155+
DecorationPassthroughNV = 5250,
156+
DecorationViewportRelativeNV = 5252,
157+
diff --git a/test/NoSignedUnsignedWrap.ll b/test/NoSignedUnsignedWrap.ll
158+
new file mode 100644
159+
index 0000000..049a39e
160+
--- /dev/null
161+
+++ b/test/NoSignedUnsignedWrap.ll
162+
@@ -0,0 +1,38 @@
163+
+; Source
164+
+; int square(unsigned short a) {
165+
+; return a * a;
166+
+; }
167+
+; Command
168+
+; clang -cc1 -triple spir -emit-llvm -O2 -o NoSignedUnsignedWrap.ll test.cl
169+
+
170+
+; RUN: llvm-as %s -o %t.bc
171+
+; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
172+
+
173+
+; RUN: llvm-spirv %t.bc -o %t.spv
174+
+; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
175+
+; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
176+
+
177+
+; CHECK-SPIRV: Decorate {{[0-9]+}} NoSignedWrap
178+
+; CHECK-SPIRV: Decorate {{[0-9]+}} NoUnsignedWrap
179+
+
180+
+target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
181+
+target triple = "spir"
182+
+
183+
+; Function Attrs: norecurse nounwind readnone
184+
+define spir_func i32 @square(i16 zeroext %a) local_unnamed_addr #0 {
185+
+entry:
186+
+ %conv = zext i16 %a to i32
187+
+ ; CHECK-LLVM: mul nuw nsw
188+
+ %mul = mul nuw nsw i32 %conv, %conv
189+
+ ret i32 %mul
190+
+}
191+
+
192+
+attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "denorms-are-zero"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
193+
+
194+
+!llvm.module.flags = !{!0}
195+
+!opencl.ocl.version = !{!1}
196+
+!opencl.spir.version = !{!2}
197+
+
198+
+!0 = !{i32 1, !"wchar_size", i32 4}
199+
+!1 = !{i32 1, i32 0}
200+
+!2 = !{i32 1, i32 2}
201+
--
202+
2.7.4
203+

0 commit comments

Comments
 (0)