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