https://github.com/joaosaffran created 
https://github.com/llvm/llvm-project/pull/131739

closes: [#125754](https://github.com/llvm/llvm-project/issues/125754)

>From 145b3b1c10faffa15477083e530fcc50c71ff2ea Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saff...@microsoft.com>
Date: Tue, 18 Mar 2025 06:14:12 +0000
Subject: [PATCH 1/3] adding support to attr

---
 clang/include/clang/Basic/Attr.td             |   4 +-
 clang/lib/CodeGen/CGStmt.cpp                  |  23 ++
 clang/test/AST/HLSL/HLSLControlFlowHint.hlsl  |  59 +++++
 clang/test/AST/HLSL/HLSLControlFlowHint.ll    | 211 ++++++++++++++++++
 .../CodeGen/DirectX/HLSLControlFlowHint.ll    | 131 +++++++++++
 .../SPIRV/structurizer/HLSLControlFlowHint.ll | 125 ++++++++++-
 6 files changed, 548 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/AST/HLSL/HLSLControlFlowHint.ll

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index d9840dad6a5e2..948fc99c9b083 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4394,8 +4394,8 @@ def HLSLControlFlowHint: StmtAttr {
   /// [branch]
   /// [flatten]
   let Spellings = [Microsoft<"branch">, Microsoft<"flatten">];
-  let Subjects = SubjectList<[IfStmt],
-                              ErrorDiag, "'if' statements">;
+  let Subjects = SubjectList<[IfStmt, SwitchStmt],
+                              ErrorDiag, "'if' and 'switch' statements">;
   let LangOpts = [HLSL];
   let Documentation = [InternalOnly];
 }
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 9860f23dc9e28..ef963fc4984d4 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2276,6 +2276,29 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt 
&S) {
   // failure.
   llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default");
   SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);
+  switch (HLSLControlFlowAttr) {
+  case HLSLControlFlowHintAttr::Microsoft_branch:
+  case HLSLControlFlowHintAttr::Microsoft_flatten: {
+    llvm::MDBuilder MDHelper(CGM.getLLVMContext());
+
+    llvm::ConstantInt *BranchHintConstant =
+        HLSLControlFlowAttr ==
+                HLSLControlFlowHintAttr::Spelling::Microsoft_branch
+            ? llvm::ConstantInt::get(CGM.Int32Ty, 1)
+            : llvm::ConstantInt::get(CGM.Int32Ty, 2);
+
+    SmallVector<llvm::Metadata *, 2> Vals(
+        {MDHelper.createString("hlsl.controlflow.hint"),
+         MDHelper.createConstant(BranchHintConstant)});
+    SwitchInsn->setMetadata("hlsl.controlflow.hint",
+                            llvm::MDNode::get(CGM.getLLVMContext(), Vals));
+    break;
+  }
+  // This is required to avoid warnings during compilation
+  case HLSLControlFlowHintAttr::SpellingNotCalculated:
+    break;
+  }
+
   if (PGO.haveRegionCounts()) {
     // Walk the SwitchCase list to find how many there are.
     uint64_t DefaultCount = 0;
diff --git a/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl 
b/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl
index c1e6d969c8d31..18263bedbe3ec 100644
--- a/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl
+++ b/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl
@@ -41,3 +41,62 @@ export int no_attr(int X){
 
     return resp;
 }
+
+// CHECK: FunctionDecl {{.*}} used flatten_switch 'int (int)'
+// CHECK: AttributedStmt
+// CHECK-NEXT: HLSLControlFlowHintAttr {{.*}} flatten
+export int flatten_switch(int X){
+    int resp;
+    [flatten] 
+    switch (X) {
+        case 0:
+        resp = -X;
+        break;
+    case 1:
+         resp = X+X;
+        break;
+    case 2:
+        resp = X * X; break;
+    }
+
+    return resp;
+}
+
+// CHECK: FunctionDecl {{.*}} used branch_switch 'int (int)'
+// CHECK: AttributedStmt
+// CHECK-NEXT: HLSLControlFlowHintAttr {{.*}} branch
+export int branch_switch(int X){
+    int resp;
+    [branch] 
+    switch (X) {
+     case 0:
+        resp = -X;
+        break;
+    case 1:
+        resp = X+X;
+        break;
+    case 2:
+        resp = X * X; break;
+    }
+
+    return resp;
+}
+
+// CHECK: FunctionDecl {{.*}} used no_attr_switch 'int (int)'
+// CHECK-NOT: AttributedStmt
+// CHECK-NOT: HLSLControlFlowHintAttr
+export int no_attr_switch(int X){
+    int resp;
+    switch (X) {
+        case 0:
+        resp = -X;
+        break;
+    case 1:
+         resp = X+X;
+        break;
+    case 2:
+        resp = X * X; break;
+    }
+
+    return resp;
+}
diff --git a/clang/test/AST/HLSL/HLSLControlFlowHint.ll 
b/clang/test/AST/HLSL/HLSLControlFlowHint.ll
new file mode 100644
index 0000000000000..0314f9d2c4751
--- /dev/null
+++ b/clang/test/AST/HLSL/HLSLControlFlowHint.ll
@@ -0,0 +1,211 @@
+; ModuleID = 
'/workspace/llvm-project/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl'
+source_filename = 
"/workspace/llvm-project/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl"
+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"
+target triple = "dxilv1.3-pc-shadermodel6.3-compute"
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define noundef i32 @_Z6branchi(i32 noundef %X) #0 {
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  %cmp = icmp sgt i32 %0, 0
+  br i1 %cmp, label %if.then, label %if.else, !hlsl.controlflow.hint !3
+
+if.then:                                          ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %2, 2
+  store i32 %mul, ptr %resp, align 4
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  %3 = load i32, ptr %resp, align 4
+  ret i32 %3
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define noundef i32 @_Z7flatteni(i32 noundef %X) #0 {
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  %cmp = icmp sgt i32 %0, 0
+  br i1 %cmp, label %if.then, label %if.else, !hlsl.controlflow.hint !4
+
+if.then:                                          ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %2, 2
+  store i32 %mul, ptr %resp, align 4
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  %3 = load i32, ptr %resp, align 4
+  ret i32 %3
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define noundef i32 @_Z7no_attri(i32 noundef %X) #0 {
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  %cmp = icmp sgt i32 %0, 0
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %2, 2
+  store i32 %mul, ptr %resp, align 4
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  %3 = load i32, ptr %resp, align 4
+  ret i32 %3
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define noundef i32 @_Z14flatten_switchi(i32 noundef %X) #0 {
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  switch i32 %0, label %sw.epilog [
+    i32 0, label %sw.bb
+    i32 1, label %sw.bb1
+    i32 2, label %sw.bb2
+  ], !hlsl.controlflow.hint !4
+
+sw.bb:                                            ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb1:                                           ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %3 = load i32, ptr %X.addr, align 4
+  %add = add nsw i32 %2, %3
+  store i32 %add, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb2:                                           ; preds = %entry
+  %4 = load i32, ptr %X.addr, align 4
+  %5 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %4, %5
+  store i32 %mul, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
+  %6 = load i32, ptr %resp, align 4
+  ret i32 %6
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define noundef i32 @_Z13branch_switchi(i32 noundef %X) #0 {
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  switch i32 %0, label %sw.epilog [
+    i32 0, label %sw.bb
+    i32 1, label %sw.bb1
+    i32 2, label %sw.bb2
+  ], !hlsl.controlflow.hint !3
+
+sw.bb:                                            ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb1:                                           ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %3 = load i32, ptr %X.addr, align 4
+  %add = add nsw i32 %2, %3
+  store i32 %add, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb2:                                           ; preds = %entry
+  %4 = load i32, ptr %X.addr, align 4
+  %5 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %4, %5
+  store i32 %mul, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
+  %6 = load i32, ptr %resp, align 4
+  ret i32 %6
+}
+
+; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
+define noundef i32 @_Z14no_attr_switchi(i32 noundef %X) #0 {
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  switch i32 %0, label %sw.epilog [
+    i32 0, label %sw.bb
+    i32 1, label %sw.bb1
+    i32 2, label %sw.bb2
+  ]
+
+sw.bb:                                            ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb1:                                           ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %3 = load i32, ptr %X.addr, align 4
+  %add = add nsw i32 %2, %3
+  store i32 %add, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb2:                                           ; preds = %entry
+  %4 = load i32, ptr %X.addr, align 4
+  %5 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %4, %5
+  store i32 %mul, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
+  %6 = load i32, ptr %resp, align 4
+  ret i32 %6
+}
+
+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" }
+
+!llvm.module.flags = !{!0}
+!dx.valver = !{!1}
+!llvm.ident = !{!2}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, i32 8}
+!2 = !{!"clang version 21.0.0git 
(https://github.com/joaosaffran/llvm-project.git 
fe0db909f0b0d61dbc0d2f7a3313138808c20194)"}
+!3 = !{!"hlsl.controlflow.hint", i32 1}
+!4 = !{!"hlsl.controlflow.hint", i32 2}
diff --git a/llvm/test/CodeGen/DirectX/HLSLControlFlowHint.ll 
b/llvm/test/CodeGen/DirectX/HLSLControlFlowHint.ll
index 6a5274429930e..00dd374daf460 100644
--- a/llvm/test/CodeGen/DirectX/HLSLControlFlowHint.ll
+++ b/llvm/test/CodeGen/DirectX/HLSLControlFlowHint.ll
@@ -91,6 +91,137 @@ if.end:                                           ; preds = 
%if.else, %if.then
   %3 = load i32, ptr %resp, align 4
   ret i32 %3
 }
+
+; CHECK: define i32 @flatten_switch(i32 %X)
+; CHECK-NOT: hlsl.controlflow.hint
+; CHECK:      switch i32 %0, label %sw.epilog [
+; CHECK-NEXT:   i32 0, label %sw.bb
+; CHECK-NEXT:   i32 1, label %sw.bb1
+; CHECK-NEXT:   i32 2, label %sw.bb2
+; CHECK-NEXT: ], !dx.controlflow.hints [[HINT_FLATTEN]]
+define i32 @flatten_switch(i32 %X) #0 {
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  switch i32 %0, label %sw.epilog [
+    i32 0, label %sw.bb
+    i32 1, label %sw.bb1
+    i32 2, label %sw.bb2
+  ], !hlsl.controlflow.hint !1
+
+sw.bb:                                            ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb1:                                           ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %3 = load i32, ptr %X.addr, align 4
+  %add = add nsw i32 %2, %3
+  store i32 %add, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb2:                                           ; preds = %entry
+  %4 = load i32, ptr %X.addr, align 4
+  %5 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %4, %5
+  store i32 %mul, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
+  %6 = load i32, ptr %resp, align 4
+  ret i32 %6
+}
+
+
+; CHECK: define i32 @branch_switch(i32 %X)
+; CHECK-NOT: hlsl.controlflow.hint
+; CHECK:      switch i32 %0, label %sw.epilog [
+; CHECK-NEXT:   i32 0, label %sw.bb
+; CHECK-NEXT:   i32 1, label %sw.bb1
+; CHECK-NEXT:   i32 2, label %sw.bb2
+; CHECK-NEXT: ], !dx.controlflow.hints [[HINT_BRANCH]]
+define i32 @branch_switch(i32 %X) #0 {
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  switch i32 %0, label %sw.epilog [
+    i32 0, label %sw.bb
+    i32 1, label %sw.bb1
+    i32 2, label %sw.bb2
+  ], !hlsl.controlflow.hint !0
+
+sw.bb:                                            ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb1:                                           ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %3 = load i32, ptr %X.addr, align 4
+  %add = add nsw i32 %2, %3
+  store i32 %add, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb2:                                           ; preds = %entry
+  %4 = load i32, ptr %X.addr, align 4
+  %5 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %4, %5
+  store i32 %mul, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
+  %6 = load i32, ptr %resp, align 4
+  ret i32 %6
+}
+
+
+; CHECK: define i32 @no_attr_switch(i32 %X)
+; CHECK-NOT: hlsl.controlflow.hint
+; CHECK-NOT: !dx.controlflow.hints
+define i32 @no_attr_switch(i32 %X) #0 {
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  switch i32 %0, label %sw.epilog [
+    i32 0, label %sw.bb
+    i32 1, label %sw.bb1
+    i32 2, label %sw.bb2
+  ]
+
+sw.bb:                                            ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb1:                                           ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %3 = load i32, ptr %X.addr, align 4
+  %add = add nsw i32 %2, %3
+  store i32 %add, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb2:                                           ; preds = %entry
+  %4 = load i32, ptr %X.addr, align 4
+  %5 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %4, %5
+  store i32 %mul, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
+  %6 = load i32, ptr %resp, align 4
+  ret i32 %6
+}
+
 ; CHECK-NOT: hlsl.controlflow.hint
 ; CHECK: [[HINT_BRANCH]] = !{!"dx.controlflow.hints", i32 1}
 ; CHECK: [[HINT_FLATTEN]] = !{!"dx.controlflow.hints", i32 2}
diff --git a/llvm/test/CodeGen/SPIRV/structurizer/HLSLControlFlowHint.ll 
b/llvm/test/CodeGen/SPIRV/structurizer/HLSLControlFlowHint.ll
index 848eaf70f5a19..300b1c9672c8d 100644
--- a/llvm/test/CodeGen/SPIRV/structurizer/HLSLControlFlowHint.ll
+++ b/llvm/test/CodeGen/SPIRV/structurizer/HLSLControlFlowHint.ll
@@ -5,7 +5,7 @@
 define spir_func noundef i32 @test_branch(i32 noundef %X) {
 entry:
 ; CHECK-LABEL: ; -- Begin function test_branch
-; OpSelectionMerge %[[#]] DontFlatten
+  ; CHECK: OpSelectionMerge %[[#]] DontFlatten
   %X.addr = alloca i32, align 4
   %resp = alloca i32, align 4
   store i32 %X, ptr %X.addr, align 4
@@ -34,7 +34,7 @@ if.end:                                           ; preds = 
%if.else, %if.then
 define spir_func noundef i32 @test_flatten(i32 noundef %X) {
 entry:
 ; CHECK-LABEL: ; -- Begin function test_flatten
-; OpSelectionMerge %[[#]] Flatten
+  ; CHECK: OpSelectionMerge %[[#]] Flatten
   %X.addr = alloca i32, align 4
   %resp = alloca i32, align 4
   store i32 %X, ptr %X.addr, align 4
@@ -62,7 +62,7 @@ if.end:                                           ; preds = 
%if.else, %if.then
 define spir_func noundef i32 @test_no_attr(i32 noundef %X) {
 entry:
 ; CHECK-LABEL: ; -- Begin function test_no_attr
-; OpSelectionMerge %[[#]] None
+  ; CHECK: OpSelectionMerge %[[#]] None
   %X.addr = alloca i32, align 4
   %resp = alloca i32, align 4
   store i32 %X, ptr %X.addr, align 4
@@ -87,5 +87,124 @@ if.end:                                           ; preds = 
%if.else, %if.then
   ret i32 %3
 }
 
+define spir_func noundef i32 @flatten_switch(i32 noundef %X) {
+entry:
+; CHECK-LABEL: ; -- Begin function flatten_switch
+  ; CHECK: OpSelectionMerge %[[#]] Flatten
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  switch i32 %0, label %sw.epilog [
+    i32 0, label %sw.bb
+    i32 1, label %sw.bb1
+    i32 2, label %sw.bb2
+  ], !hlsl.controlflow.hint !1
+
+sw.bb:                                            ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb1:                                           ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %3 = load i32, ptr %X.addr, align 4
+  %add = add nsw i32 %2, %3
+  store i32 %add, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb2:                                           ; preds = %entry
+  %4 = load i32, ptr %X.addr, align 4
+  %5 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %4, %5
+  store i32 %mul, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
+  %6 = load i32, ptr %resp, align 4
+  ret i32 %6
+}
+
+
+define spir_func noundef i32 @branch_switch(i32 noundef %X) {
+  entry:
+  ; CHECK-LABEL: ; -- Begin function branch_switch
+    ; CHECK: OpSelectionMerge %[[#]] DontFlatten
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  switch i32 %0, label %sw.epilog [
+    i32 0, label %sw.bb
+    i32 1, label %sw.bb1
+    i32 2, label %sw.bb2
+  ], !hlsl.controlflow.hint !0
+
+sw.bb:                                            ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb1:                                           ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %3 = load i32, ptr %X.addr, align 4
+  %add = add nsw i32 %2, %3
+  store i32 %add, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb2:                                           ; preds = %entry
+  %4 = load i32, ptr %X.addr, align 4
+  %5 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %4, %5
+  store i32 %mul, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
+  %6 = load i32, ptr %resp, align 4
+  ret i32 %6
+}
+
+
+define spir_func noundef i32 @no_attr_switch(i32 noundef %X) {
+  ; CHECK-LABEL: ; -- Begin function no_attr_switch
+  ; CHECK: OpSelectionMerge %[[#]] None
+entry:
+  %X.addr = alloca i32, align 4
+  %resp = alloca i32, align 4
+  store i32 %X, ptr %X.addr, align 4
+  %0 = load i32, ptr %X.addr, align 4
+  switch i32 %0, label %sw.epilog [
+    i32 0, label %sw.bb
+    i32 1, label %sw.bb1
+    i32 2, label %sw.bb2
+  ]
+
+sw.bb:                                            ; preds = %entry
+  %1 = load i32, ptr %X.addr, align 4
+  %sub = sub nsw i32 0, %1
+  store i32 %sub, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb1:                                           ; preds = %entry
+  %2 = load i32, ptr %X.addr, align 4
+  %3 = load i32, ptr %X.addr, align 4
+  %add = add nsw i32 %2, %3
+  store i32 %add, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.bb2:                                           ; preds = %entry
+  %4 = load i32, ptr %X.addr, align 4
+  %5 = load i32, ptr %X.addr, align 4
+  %mul = mul nsw i32 %4, %5
+  store i32 %mul, ptr %resp, align 4
+  br label %sw.epilog
+
+sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
+  %6 = load i32, ptr %resp, align 4
+  ret i32 %6
+}
+
 !0 = !{!"hlsl.controlflow.hint", i32 1}
 !1 = !{!"hlsl.controlflow.hint", i32 2}

>From 814687fa0181f0401484328727a5a2c5e4ac95ee Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saff...@microsoft.com>
Date: Tue, 18 Mar 2025 06:33:59 +0000
Subject: [PATCH 2/3] removing file

---
 clang/test/AST/HLSL/HLSLControlFlowHint.ll | 211 ---------------------
 1 file changed, 211 deletions(-)
 delete mode 100644 clang/test/AST/HLSL/HLSLControlFlowHint.ll

diff --git a/clang/test/AST/HLSL/HLSLControlFlowHint.ll 
b/clang/test/AST/HLSL/HLSLControlFlowHint.ll
deleted file mode 100644
index 0314f9d2c4751..0000000000000
--- a/clang/test/AST/HLSL/HLSLControlFlowHint.ll
+++ /dev/null
@@ -1,211 +0,0 @@
-; ModuleID = 
'/workspace/llvm-project/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl'
-source_filename = 
"/workspace/llvm-project/clang/test/AST/HLSL/HLSLControlFlowHint.hlsl"
-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"
-target triple = "dxilv1.3-pc-shadermodel6.3-compute"
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define noundef i32 @_Z6branchi(i32 noundef %X) #0 {
-entry:
-  %X.addr = alloca i32, align 4
-  %resp = alloca i32, align 4
-  store i32 %X, ptr %X.addr, align 4
-  %0 = load i32, ptr %X.addr, align 4
-  %cmp = icmp sgt i32 %0, 0
-  br i1 %cmp, label %if.then, label %if.else, !hlsl.controlflow.hint !3
-
-if.then:                                          ; preds = %entry
-  %1 = load i32, ptr %X.addr, align 4
-  %sub = sub nsw i32 0, %1
-  store i32 %sub, ptr %resp, align 4
-  br label %if.end
-
-if.else:                                          ; preds = %entry
-  %2 = load i32, ptr %X.addr, align 4
-  %mul = mul nsw i32 %2, 2
-  store i32 %mul, ptr %resp, align 4
-  br label %if.end
-
-if.end:                                           ; preds = %if.else, %if.then
-  %3 = load i32, ptr %resp, align 4
-  ret i32 %3
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define noundef i32 @_Z7flatteni(i32 noundef %X) #0 {
-entry:
-  %X.addr = alloca i32, align 4
-  %resp = alloca i32, align 4
-  store i32 %X, ptr %X.addr, align 4
-  %0 = load i32, ptr %X.addr, align 4
-  %cmp = icmp sgt i32 %0, 0
-  br i1 %cmp, label %if.then, label %if.else, !hlsl.controlflow.hint !4
-
-if.then:                                          ; preds = %entry
-  %1 = load i32, ptr %X.addr, align 4
-  %sub = sub nsw i32 0, %1
-  store i32 %sub, ptr %resp, align 4
-  br label %if.end
-
-if.else:                                          ; preds = %entry
-  %2 = load i32, ptr %X.addr, align 4
-  %mul = mul nsw i32 %2, 2
-  store i32 %mul, ptr %resp, align 4
-  br label %if.end
-
-if.end:                                           ; preds = %if.else, %if.then
-  %3 = load i32, ptr %resp, align 4
-  ret i32 %3
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define noundef i32 @_Z7no_attri(i32 noundef %X) #0 {
-entry:
-  %X.addr = alloca i32, align 4
-  %resp = alloca i32, align 4
-  store i32 %X, ptr %X.addr, align 4
-  %0 = load i32, ptr %X.addr, align 4
-  %cmp = icmp sgt i32 %0, 0
-  br i1 %cmp, label %if.then, label %if.else
-
-if.then:                                          ; preds = %entry
-  %1 = load i32, ptr %X.addr, align 4
-  %sub = sub nsw i32 0, %1
-  store i32 %sub, ptr %resp, align 4
-  br label %if.end
-
-if.else:                                          ; preds = %entry
-  %2 = load i32, ptr %X.addr, align 4
-  %mul = mul nsw i32 %2, 2
-  store i32 %mul, ptr %resp, align 4
-  br label %if.end
-
-if.end:                                           ; preds = %if.else, %if.then
-  %3 = load i32, ptr %resp, align 4
-  ret i32 %3
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define noundef i32 @_Z14flatten_switchi(i32 noundef %X) #0 {
-entry:
-  %X.addr = alloca i32, align 4
-  %resp = alloca i32, align 4
-  store i32 %X, ptr %X.addr, align 4
-  %0 = load i32, ptr %X.addr, align 4
-  switch i32 %0, label %sw.epilog [
-    i32 0, label %sw.bb
-    i32 1, label %sw.bb1
-    i32 2, label %sw.bb2
-  ], !hlsl.controlflow.hint !4
-
-sw.bb:                                            ; preds = %entry
-  %1 = load i32, ptr %X.addr, align 4
-  %sub = sub nsw i32 0, %1
-  store i32 %sub, ptr %resp, align 4
-  br label %sw.epilog
-
-sw.bb1:                                           ; preds = %entry
-  %2 = load i32, ptr %X.addr, align 4
-  %3 = load i32, ptr %X.addr, align 4
-  %add = add nsw i32 %2, %3
-  store i32 %add, ptr %resp, align 4
-  br label %sw.epilog
-
-sw.bb2:                                           ; preds = %entry
-  %4 = load i32, ptr %X.addr, align 4
-  %5 = load i32, ptr %X.addr, align 4
-  %mul = mul nsw i32 %4, %5
-  store i32 %mul, ptr %resp, align 4
-  br label %sw.epilog
-
-sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
-  %6 = load i32, ptr %resp, align 4
-  ret i32 %6
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define noundef i32 @_Z13branch_switchi(i32 noundef %X) #0 {
-entry:
-  %X.addr = alloca i32, align 4
-  %resp = alloca i32, align 4
-  store i32 %X, ptr %X.addr, align 4
-  %0 = load i32, ptr %X.addr, align 4
-  switch i32 %0, label %sw.epilog [
-    i32 0, label %sw.bb
-    i32 1, label %sw.bb1
-    i32 2, label %sw.bb2
-  ], !hlsl.controlflow.hint !3
-
-sw.bb:                                            ; preds = %entry
-  %1 = load i32, ptr %X.addr, align 4
-  %sub = sub nsw i32 0, %1
-  store i32 %sub, ptr %resp, align 4
-  br label %sw.epilog
-
-sw.bb1:                                           ; preds = %entry
-  %2 = load i32, ptr %X.addr, align 4
-  %3 = load i32, ptr %X.addr, align 4
-  %add = add nsw i32 %2, %3
-  store i32 %add, ptr %resp, align 4
-  br label %sw.epilog
-
-sw.bb2:                                           ; preds = %entry
-  %4 = load i32, ptr %X.addr, align 4
-  %5 = load i32, ptr %X.addr, align 4
-  %mul = mul nsw i32 %4, %5
-  store i32 %mul, ptr %resp, align 4
-  br label %sw.epilog
-
-sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
-  %6 = load i32, ptr %resp, align 4
-  ret i32 %6
-}
-
-; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind
-define noundef i32 @_Z14no_attr_switchi(i32 noundef %X) #0 {
-entry:
-  %X.addr = alloca i32, align 4
-  %resp = alloca i32, align 4
-  store i32 %X, ptr %X.addr, align 4
-  %0 = load i32, ptr %X.addr, align 4
-  switch i32 %0, label %sw.epilog [
-    i32 0, label %sw.bb
-    i32 1, label %sw.bb1
-    i32 2, label %sw.bb2
-  ]
-
-sw.bb:                                            ; preds = %entry
-  %1 = load i32, ptr %X.addr, align 4
-  %sub = sub nsw i32 0, %1
-  store i32 %sub, ptr %resp, align 4
-  br label %sw.epilog
-
-sw.bb1:                                           ; preds = %entry
-  %2 = load i32, ptr %X.addr, align 4
-  %3 = load i32, ptr %X.addr, align 4
-  %add = add nsw i32 %2, %3
-  store i32 %add, ptr %resp, align 4
-  br label %sw.epilog
-
-sw.bb2:                                           ; preds = %entry
-  %4 = load i32, ptr %X.addr, align 4
-  %5 = load i32, ptr %X.addr, align 4
-  %mul = mul nsw i32 %4, %5
-  store i32 %mul, ptr %resp, align 4
-  br label %sw.epilog
-
-sw.epilog:                                        ; preds = %entry, %sw.bb2, 
%sw.bb1, %sw.bb
-  %6 = load i32, ptr %resp, align 4
-  ret i32 %6
-}
-
-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" }
-
-!llvm.module.flags = !{!0}
-!dx.valver = !{!1}
-!llvm.ident = !{!2}
-
-!0 = !{i32 1, !"wchar_size", i32 4}
-!1 = !{i32 1, i32 8}
-!2 = !{!"clang version 21.0.0git 
(https://github.com/joaosaffran/llvm-project.git 
fe0db909f0b0d61dbc0d2f7a3313138808c20194)"}
-!3 = !{!"hlsl.controlflow.hint", i32 1}
-!4 = !{!"hlsl.controlflow.hint", i32 2}

>From e8fbd9675a033592a315c8d1f097edf701bbdb4c Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saff...@microsoft.com>
Date: Tue, 18 Mar 2025 06:35:08 +0000
Subject: [PATCH 3/3] fix format

---
 .../SPIRV/structurizer/HLSLControlFlowHint.ll        | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/structurizer/HLSLControlFlowHint.ll 
b/llvm/test/CodeGen/SPIRV/structurizer/HLSLControlFlowHint.ll
index 300b1c9672c8d..9c6f977dc9b34 100644
--- a/llvm/test/CodeGen/SPIRV/structurizer/HLSLControlFlowHint.ll
+++ b/llvm/test/CodeGen/SPIRV/structurizer/HLSLControlFlowHint.ll
@@ -5,7 +5,7 @@
 define spir_func noundef i32 @test_branch(i32 noundef %X) {
 entry:
 ; CHECK-LABEL: ; -- Begin function test_branch
-  ; CHECK: OpSelectionMerge %[[#]] DontFlatten
+; CHECK: OpSelectionMerge %[[#]] DontFlatten
   %X.addr = alloca i32, align 4
   %resp = alloca i32, align 4
   store i32 %X, ptr %X.addr, align 4
@@ -34,7 +34,7 @@ if.end:                                           ; preds = 
%if.else, %if.then
 define spir_func noundef i32 @test_flatten(i32 noundef %X) {
 entry:
 ; CHECK-LABEL: ; -- Begin function test_flatten
-  ; CHECK: OpSelectionMerge %[[#]] Flatten
+; CHECK: OpSelectionMerge %[[#]] Flatten
   %X.addr = alloca i32, align 4
   %resp = alloca i32, align 4
   store i32 %X, ptr %X.addr, align 4
@@ -62,7 +62,7 @@ if.end:                                           ; preds = 
%if.else, %if.then
 define spir_func noundef i32 @test_no_attr(i32 noundef %X) {
 entry:
 ; CHECK-LABEL: ; -- Begin function test_no_attr
-  ; CHECK: OpSelectionMerge %[[#]] None
+; CHECK: OpSelectionMerge %[[#]] None
   %X.addr = alloca i32, align 4
   %resp = alloca i32, align 4
   store i32 %X, ptr %X.addr, align 4
@@ -90,7 +90,7 @@ if.end:                                           ; preds = 
%if.else, %if.then
 define spir_func noundef i32 @flatten_switch(i32 noundef %X) {
 entry:
 ; CHECK-LABEL: ; -- Begin function flatten_switch
-  ; CHECK: OpSelectionMerge %[[#]] Flatten
+; CHECK: OpSelectionMerge %[[#]] Flatten
   %X.addr = alloca i32, align 4
   %resp = alloca i32, align 4
   store i32 %X, ptr %X.addr, align 4
@@ -130,7 +130,7 @@ sw.epilog:                                        ; preds = 
%entry, %sw.bb2, %sw
 define spir_func noundef i32 @branch_switch(i32 noundef %X) {
   entry:
   ; CHECK-LABEL: ; -- Begin function branch_switch
-    ; CHECK: OpSelectionMerge %[[#]] DontFlatten
+  ; CHECK: OpSelectionMerge %[[#]] DontFlatten
   %X.addr = alloca i32, align 4
   %resp = alloca i32, align 4
   store i32 %X, ptr %X.addr, align 4
@@ -169,7 +169,7 @@ sw.epilog:                                        ; preds = 
%entry, %sw.bb2, %sw
 
 define spir_func noundef i32 @no_attr_switch(i32 noundef %X) {
   ; CHECK-LABEL: ; -- Begin function no_attr_switch
-  ; CHECK: OpSelectionMerge %[[#]] None
+; CHECK: OpSelectionMerge %[[#]] None
 entry:
   %X.addr = alloca i32, align 4
   %resp = alloca i32, align 4

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to