Skip to content

Commit 7600713

Browse files
authored
[LLVM] New NoDivergenceSource function attribute (#111832)
A call to a function that has this attribute is not a source of divergence, as used by UniformityAnalysis. That allows a front-end to use known-name calls as an instruction extension mechanism (e.g. https://github.com/GPUOpen-Drivers/llvm-dialects ) without such a call being a source of divergence.
1 parent 3292ce0 commit 7600713

File tree

9 files changed

+41
-0
lines changed

9 files changed

+41
-0
lines changed

llvm/docs/LangRef.rst

+6
Original file line numberDiff line numberDiff line change
@@ -2082,6 +2082,12 @@ example:
20822082
function call, use of ``longjmp``, or other means. It is a compiler hint that
20832083
is used at module level to improve dataflow analysis, dropped during linking,
20842084
and has no effect on functions defined in the current module.
2085+
``nodivergencesource``
2086+
A call to this function is not a source of divergence. In uniformity
2087+
analysis, a *source of divergence* is an instruction that generates
2088+
divergence even if its inputs are uniform. A call with no further information
2089+
would normally be considered a source of divergence; setting this attribute
2090+
on a function means that a call to it is not a source of divergence.
20852091
``noduplicate``
20862092
This attribute indicates that calls to the function cannot be
20872093
duplicated. A call to a ``noduplicate`` function may be moved

llvm/include/llvm/Bitcode/LLVMBitCodes.h

+1
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@ enum AttributeKindCodes {
767767
ATTR_KIND_SANITIZE_REALTIME_UNSAFE = 97,
768768
ATTR_KIND_CORO_ELIDE_SAFE = 98,
769769
ATTR_KIND_NO_EXT = 99,
770+
ATTR_KIND_NO_DIVERGENCE_SOURCE = 100,
770771
};
771772

772773
enum ComdatSelectionKindCodes {

llvm/include/llvm/IR/Attributes.td

+3
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ def NoCallback : EnumAttr<"nocallback", IntersectAnd, [FnAttr]>;
183183
/// Function creates no aliases of pointer.
184184
def NoCapture : EnumAttr<"nocapture", IntersectAnd, [ParamAttr]>;
185185

186+
/// Function is not a source of divergence.
187+
def NoDivergenceSource : EnumAttr<"nodivergencesource", IntersectAnd, [FnAttr]>;
188+
186189
/// Call cannot be duplicated.
187190
def NoDuplicate : EnumAttr<"noduplicate", IntersectPreserve, [FnAttr]>;
188191

llvm/lib/Analysis/TargetTransformInfo.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,10 @@ bool TargetTransformInfo::hasBranchDivergence(const Function *F) const {
292292
}
293293

294294
bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const {
295+
if (const auto *Call = dyn_cast<CallBase>(V)) {
296+
if (Call->hasFnAttr(Attribute::NoDivergenceSource))
297+
return false;
298+
}
295299
return TTIImpl->isSourceOfDivergence(V);
296300
}
297301

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
20662066
return Attribute::NoCallback;
20672067
case bitc::ATTR_KIND_NO_CAPTURE:
20682068
return Attribute::NoCapture;
2069+
case bitc::ATTR_KIND_NO_DIVERGENCE_SOURCE:
2070+
return Attribute::NoDivergenceSource;
20692071
case bitc::ATTR_KIND_NO_DUPLICATE:
20702072
return Attribute::NoDuplicate;
20712073
case bitc::ATTR_KIND_NOFREE:

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
763763
return bitc::ATTR_KIND_NO_CALLBACK;
764764
case Attribute::NoCapture:
765765
return bitc::ATTR_KIND_NO_CAPTURE;
766+
case Attribute::NoDivergenceSource:
767+
return bitc::ATTR_KIND_NO_DIVERGENCE_SOURCE;
766768
case Attribute::NoDuplicate:
767769
return bitc::ATTR_KIND_NO_DUPLICATE;
768770
case Attribute::NoFree:

llvm/lib/Transforms/Utils/CodeExtractor.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
917917
case Attribute::NoFPClass:
918918
case Attribute::CoroDestroyOnlyWhenComplete:
919919
case Attribute::CoroElideSafe:
920+
case Attribute::NoDivergenceSource:
920921
continue;
921922
// Those attributes should be safe to propagate to the extracted function.
922923
case Attribute::AlwaysInline:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: opt -mtriple amdgcn-- -passes='print<uniformity>' -disable-output %s 2>&1 | FileCheck %s
2+
3+
; CHECK: DIVERGENT: %divergentval
4+
; CHECK-NOT: DIVERGENT: %uniformval
5+
; CHECK: %uniformval
6+
define void @test() {
7+
%divergentval = call i32 @normalfunc()
8+
%uniformval = call i32 @nodivergencesourcefunc()
9+
ret void
10+
}
11+
12+
declare i32 @normalfunc() #0
13+
declare i32 @nodivergencesourcefunc() #1
14+
15+
attributes #0 = { nounwind }
16+
attributes #1 = { nounwind nodivergencesource }

llvm/test/Bitcode/attributes.ll

+6
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,11 @@ define void @f91(ptr dead_on_unwind %p) {
537537
ret void
538538
}
539539

540+
; CHECK: define void @f94() [[NODIVERGENCESOURCE:#[0-9]+]]
541+
define void @f94() nodivergencesource {
542+
ret void;
543+
}
544+
540545
; CHECK: define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a)
541546
define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a) {
542547
ret i32 0
@@ -615,4 +620,5 @@ define void @initializes(ptr initializes((-4, 0), (4, 8)) %a) {
615620
; CHECK: attributes [[FNRETTHUNKEXTERN]] = { fn_ret_thunk_extern }
616621
; CHECK: attributes [[SKIPPROFILE]] = { skipprofile }
617622
; CHECK: attributes [[OPTDEBUG]] = { optdebug }
623+
; CHECK: attributes [[NODIVERGENCESOURCE]] = { nodivergencesource }
618624
; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin }

0 commit comments

Comments
 (0)