Skip to content

Commit 636802e

Browse files
author
joaosaffran
committed
Revert "Revert llvm#116331 & llvm#121852 (llvm#122105)"
This reverts commit b66f6b2.
1 parent d6ae3d3 commit 636802e

File tree

14 files changed

+516
-19
lines changed

14 files changed

+516
-19
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4335,6 +4335,16 @@ def HLSLLoopHint: StmtAttr {
43354335
let Documentation = [HLSLLoopHintDocs, HLSLUnrollHintDocs];
43364336
}
43374337

4338+
def HLSLControlFlowHint: StmtAttr {
4339+
/// [branch]
4340+
/// [flatten]
4341+
let Spellings = [Microsoft<"branch">, Microsoft<"flatten">];
4342+
let Subjects = SubjectList<[IfStmt],
4343+
ErrorDiag, "'if' statements">;
4344+
let LangOpts = [HLSL];
4345+
let Documentation = [InternalOnly];
4346+
}
4347+
43384348
def CapturedRecord : InheritableAttr {
43394349
// This attribute has no spellings as it is only ever created implicitly.
43404350
let Spellings = [];

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,8 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) {
757757
bool noinline = false;
758758
bool alwaysinline = false;
759759
bool noconvergent = false;
760+
HLSLControlFlowHintAttr::Spelling flattenOrBranch =
761+
HLSLControlFlowHintAttr::SpellingNotCalculated;
760762
const CallExpr *musttail = nullptr;
761763

762764
for (const auto *A : S.getAttrs()) {
@@ -788,13 +790,17 @@ void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) {
788790
Builder.CreateAssumption(AssumptionVal);
789791
}
790792
} break;
793+
case attr::HLSLControlFlowHint: {
794+
flattenOrBranch = cast<HLSLControlFlowHintAttr>(A)->getSemanticSpelling();
795+
} break;
791796
}
792797
}
793798
SaveAndRestore save_nomerge(InNoMergeAttributedStmt, nomerge);
794799
SaveAndRestore save_noinline(InNoInlineAttributedStmt, noinline);
795800
SaveAndRestore save_alwaysinline(InAlwaysInlineAttributedStmt, alwaysinline);
796801
SaveAndRestore save_noconvergent(InNoConvergentAttributedStmt, noconvergent);
797802
SaveAndRestore save_musttail(MustTailCall, musttail);
803+
SaveAndRestore save_flattenOrBranch(HLSLControlFlowAttr, flattenOrBranch);
798804
EmitStmt(S.getSubStmt(), S.getAttrs());
799805
}
800806

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "llvm/IR/DataLayout.h"
4141
#include "llvm/IR/Dominators.h"
4242
#include "llvm/IR/FPEnv.h"
43+
#include "llvm/IR/Instruction.h"
4344
#include "llvm/IR/IntrinsicInst.h"
4445
#include "llvm/IR/Intrinsics.h"
4546
#include "llvm/IR/MDBuilder.h"
@@ -2083,7 +2084,29 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
20832084
Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);
20842085
}
20852086

2086-
Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights, Unpredictable);
2087+
llvm::Instruction *BrInst = Builder.CreateCondBr(CondV, TrueBlock, FalseBlock,
2088+
Weights, Unpredictable);
2089+
switch (HLSLControlFlowAttr) {
2090+
case HLSLControlFlowHintAttr::Microsoft_branch:
2091+
case HLSLControlFlowHintAttr::Microsoft_flatten: {
2092+
llvm::MDBuilder MDHelper(CGM.getLLVMContext());
2093+
2094+
llvm::ConstantInt *BranchHintConstant =
2095+
HLSLControlFlowAttr ==
2096+
HLSLControlFlowHintAttr::Spelling::Microsoft_branch
2097+
? llvm::ConstantInt::get(CGM.Int32Ty, 1)
2098+
: llvm::ConstantInt::get(CGM.Int32Ty, 2);
2099+
2100+
SmallVector<llvm::Metadata *, 2> Vals(
2101+
{MDHelper.createString("hlsl.controlflow.hint"),
2102+
MDHelper.createConstant(BranchHintConstant)});
2103+
BrInst->setMetadata("hlsl.controlflow.hint",
2104+
llvm::MDNode::get(CGM.getLLVMContext(), Vals));
2105+
break;
2106+
}
2107+
case HLSLControlFlowHintAttr::SpellingNotCalculated:
2108+
break;
2109+
}
20872110
}
20882111

20892112
/// ErrorUnsupported - Print out an error that codegen doesn't support the

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,10 @@ class CodeGenFunction : public CodeGenTypeCache {
615615
/// True if the current statement has noconvergent attribute.
616616
bool InNoConvergentAttributedStmt = false;
617617

618+
/// HLSL Branch attribute.
619+
HLSLControlFlowHintAttr::Spelling HLSLControlFlowAttr =
620+
HLSLControlFlowHintAttr::SpellingNotCalculated;
621+
618622
// The CallExpr within the current statement that the musttail attribute
619623
// applies to. nullptr if there is no 'musttail' on the current statement.
620624
const CallExpr *MustTailCall = nullptr;

clang/lib/Sema/SemaStmtAttr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,12 @@ static Attr *handleHLSLLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A,
619619
return ::new (S.Context) HLSLLoopHintAttr(S.Context, A, UnrollFactor);
620620
}
621621

622+
static Attr *handleHLSLControlFlowHint(Sema &S, Stmt *St, const ParsedAttr &A,
623+
SourceRange Range) {
624+
625+
return ::new (S.Context) HLSLControlFlowHintAttr(S.Context, A);
626+
}
627+
622628
static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
623629
SourceRange Range) {
624630
if (A.isInvalid() || A.getKind() == ParsedAttr::IgnoredAttribute)
@@ -655,6 +661,8 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
655661
return handleLoopHintAttr(S, St, A, Range);
656662
case ParsedAttr::AT_HLSLLoopHint:
657663
return handleHLSLLoopHintAttr(S, St, A, Range);
664+
case ParsedAttr::AT_HLSLControlFlowHint:
665+
return handleHLSLControlFlowHint(S, St, A, Range);
658666
case ParsedAttr::AT_OpenCLUnrollHint:
659667
return handleOpenCLUnrollHint(S, St, A, Range);
660668
case ParsedAttr::AT_Suppress:
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -ast-dump %s | FileCheck %s
2+
3+
// CHECK: FunctionDecl 0x{{[0-9A-Fa-f]+}} <{{.*}}> {{.*}} used branch 'int (int)'
4+
// CHECK: AttributedStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>
5+
// CHECK-NEXT: -HLSLControlFlowHintAttr 0x{{[0-9A-Fa-f]+}} <{{.*}}> branch
6+
export int branch(int X){
7+
int resp;
8+
[branch] if (X > 0) {
9+
resp = -X;
10+
} else {
11+
resp = X * 2;
12+
}
13+
14+
return resp;
15+
}
16+
17+
// CHECK: FunctionDecl 0x{{[0-9A-Fa-f]+}} <{{.*}}> {{.*}} used flatten 'int (int)'
18+
// CHECK: AttributedStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>
19+
// CHECK-NEXT: -HLSLControlFlowHintAttr 0x{{[0-9A-Fa-f]+}} <{{.*}}> flatten
20+
export int flatten(int X){
21+
int resp;
22+
[flatten] if (X > 0) {
23+
resp = -X;
24+
} else {
25+
resp = X * 2;
26+
}
27+
28+
return resp;
29+
}
30+
31+
// CHECK: FunctionDecl 0x{{[0-9A-Fa-f]+}} <{{.*}}> {{.*}} used no_attr 'int (int)'
32+
// CHECK-NOT: AttributedStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>
33+
// CHECK-NOT: -HLSLControlFlowHintAttr
34+
export int no_attr(int X){
35+
int resp;
36+
if (X > 0) {
37+
resp = -X;
38+
} else {
39+
resp = X * 2;
40+
}
41+
42+
return resp;
43+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s -fnative-half-type -emit-llvm -o - | FileCheck %s
2+
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple spirv-vulkan-library %s -fnative-half-type -emit-llvm -o - | FileCheck %s
3+
4+
// CHECK: define {{.*}} i32 {{.*}}test_branch{{.*}}(i32 {{.*}} [[VALD:%.*]])
5+
// CHECK: [[PARAM:%.*]] = load i32, ptr [[VALD]].addr, align 4
6+
// CHECK: [[CMP:%.*]] = icmp sgt i32 [[PARAM]], 0
7+
// CHECK: br i1 [[CMP]], label %if.then, label %if.else, !hlsl.controlflow.hint [[HINT_BRANCH:![0-9]+]]
8+
export int test_branch(int X){
9+
int resp;
10+
[branch] if (X > 0) {
11+
resp = -X;
12+
} else {
13+
resp = X * 2;
14+
}
15+
16+
return resp;
17+
}
18+
19+
// CHECK: define {{.*}} i32 {{.*}}test_flatten{{.*}}(i32 {{.*}} [[VALD:%.*]])
20+
// CHECK: [[PARAM:%.*]] = load i32, ptr [[VALD]].addr, align 4
21+
// CHECK: [[CMP:%.*]] = icmp sgt i32 [[PARAM]], 0
22+
// CHECK: br i1 [[CMP]], label %if.then, label %if.else, !hlsl.controlflow.hint [[HINT_FLATTEN:![0-9]+]]
23+
export int test_flatten(int X){
24+
int resp;
25+
[flatten] if (X > 0) {
26+
resp = -X;
27+
} else {
28+
resp = X * 2;
29+
}
30+
31+
return resp;
32+
}
33+
34+
// CHECK: define {{.*}} i32 {{.*}}test_no_attr{{.*}}(i32 {{.*}} [[VALD:%.*]])
35+
// CHECK-NOT: !hlsl.controlflow.hint
36+
export int test_no_attr(int X){
37+
int resp;
38+
if (X > 0) {
39+
resp = -X;
40+
} else {
41+
resp = X * 2;
42+
}
43+
44+
return resp;
45+
}
46+
47+
//CHECK: [[HINT_BRANCH]] = !{!"hlsl.controlflow.hint", i32 1}
48+
//CHECK: [[HINT_FLATTEN]] = !{!"hlsl.controlflow.hint", i32 2}

llvm/include/llvm/IR/IntrinsicsSPIRV.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ let TargetPrefix = "spv" in {
3333
def int_spv_ptrcast : Intrinsic<[llvm_any_ty], [llvm_any_ty, llvm_metadata_ty, llvm_i32_ty], [ImmArg<ArgIndex<2>>]>;
3434
def int_spv_switch : Intrinsic<[], [llvm_any_ty, llvm_vararg_ty]>;
3535
def int_spv_loop_merge : Intrinsic<[], [llvm_vararg_ty]>;
36-
def int_spv_selection_merge : Intrinsic<[], [llvm_vararg_ty]>;
36+
def int_spv_selection_merge : Intrinsic<[], [llvm_any_ty, llvm_i32_ty], [ImmArg<ArgIndex<1>>]>;
3737
def int_spv_cmpxchg : Intrinsic<[llvm_i32_ty], [llvm_any_ty, llvm_vararg_ty]>;
3838
def int_spv_unreachable : Intrinsic<[], []>;
3939
def int_spv_alloca : Intrinsic<[llvm_any_ty], [llvm_i8_ty], [ImmArg<ArgIndex<0>>]>;

llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
#include "llvm/ADT/Twine.h"
1616
#include "llvm/Analysis/DXILMetadataAnalysis.h"
1717
#include "llvm/Analysis/DXILResource.h"
18+
#include "llvm/IR/BasicBlock.h"
1819
#include "llvm/IR/Constants.h"
1920
#include "llvm/IR/DiagnosticInfo.h"
2021
#include "llvm/IR/DiagnosticPrinter.h"
2122
#include "llvm/IR/Function.h"
2223
#include "llvm/IR/IRBuilder.h"
2324
#include "llvm/IR/LLVMContext.h"
25+
#include "llvm/IR/MDBuilder.h"
2426
#include "llvm/IR/Metadata.h"
2527
#include "llvm/IR/Module.h"
2628
#include "llvm/InitializePasses.h"
@@ -300,6 +302,39 @@ static MDTuple *emitTopLevelLibraryNode(Module &M, MDNode *RMD,
300302
return constructEntryMetadata(nullptr, nullptr, RMD, Properties, Ctx);
301303
}
302304

305+
// TODO: We might need to refactor this to be more generic,
306+
// in case we need more metadata to be replaced.
307+
static void translateBranchMetadata(Module &M) {
308+
for (Function &F : M) {
309+
for (BasicBlock &BB : F) {
310+
Instruction *BBTerminatorInst = BB.getTerminator();
311+
312+
MDNode *HlslControlFlowMD =
313+
BBTerminatorInst->getMetadata("hlsl.controlflow.hint");
314+
315+
if (!HlslControlFlowMD)
316+
continue;
317+
318+
assert(HlslControlFlowMD->getNumOperands() == 2 &&
319+
"invalid operands for hlsl.controlflow.hint");
320+
321+
MDBuilder MDHelper(M.getContext());
322+
ConstantInt *Op1 =
323+
mdconst::extract<ConstantInt>(HlslControlFlowMD->getOperand(1));
324+
325+
SmallVector<llvm::Metadata *, 2> Vals(
326+
ArrayRef<Metadata *>{MDHelper.createString("dx.controlflow.hints"),
327+
MDHelper.createConstant(Op1)});
328+
329+
MDNode *MDNode = llvm::MDNode::get(M.getContext(), Vals);
330+
331+
BBTerminatorInst->setMetadata("dx.controlflow.hints", MDNode);
332+
BBTerminatorInst->setMetadata("hlsl.controlflow.hint", nullptr);
333+
}
334+
F.clearMetadata();
335+
}
336+
}
337+
303338
static void translateMetadata(Module &M, DXILBindingMap &DBM,
304339
DXILResourceTypeMap &DRTM,
305340
const Resources &MDResources,
@@ -372,6 +407,7 @@ PreservedAnalyses DXILTranslateMetadata::run(Module &M,
372407
const dxil::ModuleMetadataInfo MMDI = MAM.getResult<DXILMetadataAnalysis>(M);
373408

374409
translateMetadata(M, DBM, DRTM, MDResources, ShaderFlags, MMDI);
410+
translateBranchMetadata(M);
375411

376412
return PreservedAnalyses::all();
377413
}
@@ -409,6 +445,7 @@ class DXILTranslateMetadataLegacy : public ModulePass {
409445
getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
410446

411447
translateMetadata(M, DBM, DRTM, MDResources, ShaderFlags, MMDI);
448+
translateBranchMetadata(M);
412449
return true;
413450
}
414451
};

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "llvm/CodeGen/TargetOpcodes.h"
3434
#include "llvm/IR/IntrinsicsSPIRV.h"
3535
#include "llvm/Support/Debug.h"
36+
#include "llvm/Support/ErrorHandling.h"
3637

3738
#define DEBUG_TYPE "spirv-isel"
3839

@@ -45,6 +46,17 @@ using ExtInstList =
4546

4647
namespace {
4748

49+
llvm::SPIRV::SelectionControl::SelectionControl
50+
getSelectionOperandForImm(int Imm) {
51+
if (Imm == 2)
52+
return SPIRV::SelectionControl::Flatten;
53+
if (Imm == 1)
54+
return SPIRV::SelectionControl::DontFlatten;
55+
if (Imm == 0)
56+
return SPIRV::SelectionControl::None;
57+
llvm_unreachable("Invalid immediate");
58+
}
59+
4860
#define GET_GLOBALISEL_PREDICATE_BITSET
4961
#include "SPIRVGenGlobalISel.inc"
5062
#undef GET_GLOBALISEL_PREDICATE_BITSET
@@ -2818,19 +2830,24 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
28182830
}
28192831
return MIB.constrainAllUses(TII, TRI, RBI);
28202832
}
2821-
case Intrinsic::spv_loop_merge:
2822-
case Intrinsic::spv_selection_merge: {
2823-
const auto Opcode = IID == Intrinsic::spv_selection_merge
2824-
? SPIRV::OpSelectionMerge
2825-
: SPIRV::OpLoopMerge;
2826-
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode));
2833+
case Intrinsic::spv_loop_merge: {
2834+
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpLoopMerge));
28272835
for (unsigned i = 1; i < I.getNumExplicitOperands(); ++i) {
28282836
assert(I.getOperand(i).isMBB());
28292837
MIB.addMBB(I.getOperand(i).getMBB());
28302838
}
28312839
MIB.addImm(SPIRV::SelectionControl::None);
28322840
return MIB.constrainAllUses(TII, TRI, RBI);
28332841
}
2842+
case Intrinsic::spv_selection_merge: {
2843+
auto MIB =
2844+
BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSelectionMerge));
2845+
assert(I.getOperand(1).isMBB() &&
2846+
"operand 1 to spv_selection_merge must be a basic block");
2847+
MIB.addMBB(I.getOperand(1).getMBB());
2848+
MIB.addImm(getSelectionOperandForImm(I.getOperand(2).getImm()));
2849+
return MIB.constrainAllUses(TII, TRI, RBI);
2850+
}
28342851
case Intrinsic::spv_cmpxchg:
28352852
return selectAtomicCmpXchg(ResVReg, ResType, I);
28362853
case Intrinsic::spv_unreachable:

0 commit comments

Comments
 (0)