Skip to content

Commit 145b3b1

Browse files
author
joaosaffran
committed
adding support to attr
1 parent 6be6400 commit 145b3b1

File tree

6 files changed

+548
-5
lines changed

6 files changed

+548
-5
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4394,8 +4394,8 @@ def HLSLControlFlowHint: StmtAttr {
43944394
/// [branch]
43954395
/// [flatten]
43964396
let Spellings = [Microsoft<"branch">, Microsoft<"flatten">];
4397-
let Subjects = SubjectList<[IfStmt],
4398-
ErrorDiag, "'if' statements">;
4397+
let Subjects = SubjectList<[IfStmt, SwitchStmt],
4398+
ErrorDiag, "'if' and 'switch' statements">;
43994399
let LangOpts = [HLSL];
44004400
let Documentation = [InternalOnly];
44014401
}

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,6 +2276,29 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
22762276
// failure.
22772277
llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default");
22782278
SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);
2279+
switch (HLSLControlFlowAttr) {
2280+
case HLSLControlFlowHintAttr::Microsoft_branch:
2281+
case HLSLControlFlowHintAttr::Microsoft_flatten: {
2282+
llvm::MDBuilder MDHelper(CGM.getLLVMContext());
2283+
2284+
llvm::ConstantInt *BranchHintConstant =
2285+
HLSLControlFlowAttr ==
2286+
HLSLControlFlowHintAttr::Spelling::Microsoft_branch
2287+
? llvm::ConstantInt::get(CGM.Int32Ty, 1)
2288+
: llvm::ConstantInt::get(CGM.Int32Ty, 2);
2289+
2290+
SmallVector<llvm::Metadata *, 2> Vals(
2291+
{MDHelper.createString("hlsl.controlflow.hint"),
2292+
MDHelper.createConstant(BranchHintConstant)});
2293+
SwitchInsn->setMetadata("hlsl.controlflow.hint",
2294+
llvm::MDNode::get(CGM.getLLVMContext(), Vals));
2295+
break;
2296+
}
2297+
// This is required to avoid warnings during compilation
2298+
case HLSLControlFlowHintAttr::SpellingNotCalculated:
2299+
break;
2300+
}
2301+
22792302
if (PGO.haveRegionCounts()) {
22802303
// Walk the SwitchCase list to find how many there are.
22812304
uint64_t DefaultCount = 0;

clang/test/AST/HLSL/HLSLControlFlowHint.hlsl

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,62 @@ export int no_attr(int X){
4141

4242
return resp;
4343
}
44+
45+
// CHECK: FunctionDecl {{.*}} used flatten_switch 'int (int)'
46+
// CHECK: AttributedStmt
47+
// CHECK-NEXT: HLSLControlFlowHintAttr {{.*}} flatten
48+
export int flatten_switch(int X){
49+
int resp;
50+
[flatten]
51+
switch (X) {
52+
case 0:
53+
resp = -X;
54+
break;
55+
case 1:
56+
resp = X+X;
57+
break;
58+
case 2:
59+
resp = X * X; break;
60+
}
61+
62+
return resp;
63+
}
64+
65+
// CHECK: FunctionDecl {{.*}} used branch_switch 'int (int)'
66+
// CHECK: AttributedStmt
67+
// CHECK-NEXT: HLSLControlFlowHintAttr {{.*}} branch
68+
export int branch_switch(int X){
69+
int resp;
70+
[branch]
71+
switch (X) {
72+
case 0:
73+
resp = -X;
74+
break;
75+
case 1:
76+
resp = X+X;
77+
break;
78+
case 2:
79+
resp = X * X; break;
80+
}
81+
82+
return resp;
83+
}
84+
85+
// CHECK: FunctionDecl {{.*}} used no_attr_switch 'int (int)'
86+
// CHECK-NOT: AttributedStmt
87+
// CHECK-NOT: HLSLControlFlowHintAttr
88+
export int no_attr_switch(int X){
89+
int resp;
90+
switch (X) {
91+
case 0:
92+
resp = -X;
93+
break;
94+
case 1:
95+
resp = X+X;
96+
break;
97+
case 2:
98+
resp = X * X; break;
99+
}
100+
101+
return resp;
102+
}
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
; ModuleID = '/workspace/llvm-project/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl'
2+
source_filename = "/workspace/llvm-project/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl"
3+
target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
4+
target triple = "dxilv1.3-pc-shadermodel6.3-compute"
5+
6+
; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
7+
define noundef i32 @_Z6branchi(i32 noundef %X) #0 {
8+
entry:
9+
%X.addr = alloca i32, align 4
10+
%resp = alloca i32, align 4
11+
store i32 %X, ptr %X.addr, align 4
12+
%0 = load i32, ptr %X.addr, align 4
13+
%cmp = icmp sgt i32 %0, 0
14+
br i1 %cmp, label %if.then, label %if.else, !hlsl.controlflow.hint !3
15+
16+
if.then: ; preds = %entry
17+
%1 = load i32, ptr %X.addr, align 4
18+
%sub = sub nsw i32 0, %1
19+
store i32 %sub, ptr %resp, align 4
20+
br label %if.end
21+
22+
if.else: ; preds = %entry
23+
%2 = load i32, ptr %X.addr, align 4
24+
%mul = mul nsw i32 %2, 2
25+
store i32 %mul, ptr %resp, align 4
26+
br label %if.end
27+
28+
if.end: ; preds = %if.else, %if.then
29+
%3 = load i32, ptr %resp, align 4
30+
ret i32 %3
31+
}
32+
33+
; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
34+
define noundef i32 @_Z7flatteni(i32 noundef %X) #0 {
35+
entry:
36+
%X.addr = alloca i32, align 4
37+
%resp = alloca i32, align 4
38+
store i32 %X, ptr %X.addr, align 4
39+
%0 = load i32, ptr %X.addr, align 4
40+
%cmp = icmp sgt i32 %0, 0
41+
br i1 %cmp, label %if.then, label %if.else, !hlsl.controlflow.hint !4
42+
43+
if.then: ; preds = %entry
44+
%1 = load i32, ptr %X.addr, align 4
45+
%sub = sub nsw i32 0, %1
46+
store i32 %sub, ptr %resp, align 4
47+
br label %if.end
48+
49+
if.else: ; preds = %entry
50+
%2 = load i32, ptr %X.addr, align 4
51+
%mul = mul nsw i32 %2, 2
52+
store i32 %mul, ptr %resp, align 4
53+
br label %if.end
54+
55+
if.end: ; preds = %if.else, %if.then
56+
%3 = load i32, ptr %resp, align 4
57+
ret i32 %3
58+
}
59+
60+
; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
61+
define noundef i32 @_Z7no_attri(i32 noundef %X) #0 {
62+
entry:
63+
%X.addr = alloca i32, align 4
64+
%resp = alloca i32, align 4
65+
store i32 %X, ptr %X.addr, align 4
66+
%0 = load i32, ptr %X.addr, align 4
67+
%cmp = icmp sgt i32 %0, 0
68+
br i1 %cmp, label %if.then, label %if.else
69+
70+
if.then: ; preds = %entry
71+
%1 = load i32, ptr %X.addr, align 4
72+
%sub = sub nsw i32 0, %1
73+
store i32 %sub, ptr %resp, align 4
74+
br label %if.end
75+
76+
if.else: ; preds = %entry
77+
%2 = load i32, ptr %X.addr, align 4
78+
%mul = mul nsw i32 %2, 2
79+
store i32 %mul, ptr %resp, align 4
80+
br label %if.end
81+
82+
if.end: ; preds = %if.else, %if.then
83+
%3 = load i32, ptr %resp, align 4
84+
ret i32 %3
85+
}
86+
87+
; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
88+
define noundef i32 @_Z14flatten_switchi(i32 noundef %X) #0 {
89+
entry:
90+
%X.addr = alloca i32, align 4
91+
%resp = alloca i32, align 4
92+
store i32 %X, ptr %X.addr, align 4
93+
%0 = load i32, ptr %X.addr, align 4
94+
switch i32 %0, label %sw.epilog [
95+
i32 0, label %sw.bb
96+
i32 1, label %sw.bb1
97+
i32 2, label %sw.bb2
98+
], !hlsl.controlflow.hint !4
99+
100+
sw.bb: ; preds = %entry
101+
%1 = load i32, ptr %X.addr, align 4
102+
%sub = sub nsw i32 0, %1
103+
store i32 %sub, ptr %resp, align 4
104+
br label %sw.epilog
105+
106+
sw.bb1: ; preds = %entry
107+
%2 = load i32, ptr %X.addr, align 4
108+
%3 = load i32, ptr %X.addr, align 4
109+
%add = add nsw i32 %2, %3
110+
store i32 %add, ptr %resp, align 4
111+
br label %sw.epilog
112+
113+
sw.bb2: ; preds = %entry
114+
%4 = load i32, ptr %X.addr, align 4
115+
%5 = load i32, ptr %X.addr, align 4
116+
%mul = mul nsw i32 %4, %5
117+
store i32 %mul, ptr %resp, align 4
118+
br label %sw.epilog
119+
120+
sw.epilog: ; preds = %entry, %sw.bb2, %sw.bb1, %sw.bb
121+
%6 = load i32, ptr %resp, align 4
122+
ret i32 %6
123+
}
124+
125+
; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
126+
define noundef i32 @_Z13branch_switchi(i32 noundef %X) #0 {
127+
entry:
128+
%X.addr = alloca i32, align 4
129+
%resp = alloca i32, align 4
130+
store i32 %X, ptr %X.addr, align 4
131+
%0 = load i32, ptr %X.addr, align 4
132+
switch i32 %0, label %sw.epilog [
133+
i32 0, label %sw.bb
134+
i32 1, label %sw.bb1
135+
i32 2, label %sw.bb2
136+
], !hlsl.controlflow.hint !3
137+
138+
sw.bb: ; preds = %entry
139+
%1 = load i32, ptr %X.addr, align 4
140+
%sub = sub nsw i32 0, %1
141+
store i32 %sub, ptr %resp, align 4
142+
br label %sw.epilog
143+
144+
sw.bb1: ; preds = %entry
145+
%2 = load i32, ptr %X.addr, align 4
146+
%3 = load i32, ptr %X.addr, align 4
147+
%add = add nsw i32 %2, %3
148+
store i32 %add, ptr %resp, align 4
149+
br label %sw.epilog
150+
151+
sw.bb2: ; preds = %entry
152+
%4 = load i32, ptr %X.addr, align 4
153+
%5 = load i32, ptr %X.addr, align 4
154+
%mul = mul nsw i32 %4, %5
155+
store i32 %mul, ptr %resp, align 4
156+
br label %sw.epilog
157+
158+
sw.epilog: ; preds = %entry, %sw.bb2, %sw.bb1, %sw.bb
159+
%6 = load i32, ptr %resp, align 4
160+
ret i32 %6
161+
}
162+
163+
; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
164+
define noundef i32 @_Z14no_attr_switchi(i32 noundef %X) #0 {
165+
entry:
166+
%X.addr = alloca i32, align 4
167+
%resp = alloca i32, align 4
168+
store i32 %X, ptr %X.addr, align 4
169+
%0 = load i32, ptr %X.addr, align 4
170+
switch i32 %0, label %sw.epilog [
171+
i32 0, label %sw.bb
172+
i32 1, label %sw.bb1
173+
i32 2, label %sw.bb2
174+
]
175+
176+
sw.bb: ; preds = %entry
177+
%1 = load i32, ptr %X.addr, align 4
178+
%sub = sub nsw i32 0, %1
179+
store i32 %sub, ptr %resp, align 4
180+
br label %sw.epilog
181+
182+
sw.bb1: ; preds = %entry
183+
%2 = load i32, ptr %X.addr, align 4
184+
%3 = load i32, ptr %X.addr, align 4
185+
%add = add nsw i32 %2, %3
186+
store i32 %add, ptr %resp, align 4
187+
br label %sw.epilog
188+
189+
sw.bb2: ; preds = %entry
190+
%4 = load i32, ptr %X.addr, align 4
191+
%5 = load i32, ptr %X.addr, align 4
192+
%mul = mul nsw i32 %4, %5
193+
store i32 %mul, ptr %resp, align 4
194+
br label %sw.epilog
195+
196+
sw.epilog: ; preds = %entry, %sw.bb2, %sw.bb1, %sw.bb
197+
%6 = load i32, ptr %resp, align 4
198+
ret i32 %6
199+
}
200+
201+
attributes #0 = { alwaysinline convergent mustprogress norecurse nounwind "approx-func-fp-math"="true" "hlsl.export" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
202+
203+
!llvm.module.flags = !{!0}
204+
!dx.valver = !{!1}
205+
!llvm.ident = !{!2}
206+
207+
!0 = !{i32 1, !"wchar_size", i32 4}
208+
!1 = !{i32 1, i32 8}
209+
!2 = !{!"clang version 21.0.0git (https://github.com/joaosaffran/llvm-project.git fe0db909f0b0d61dbc0d2f7a3313138808c20194)"}
210+
!3 = !{!"hlsl.controlflow.hint", i32 1}
211+
!4 = !{!"hlsl.controlflow.hint", i32 2}

0 commit comments

Comments
 (0)