Skip to content

Commit

Permalink
[LLVM] New NoDivergenceSource function attribute (#111832)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
trenouf authored Oct 12, 2024
1 parent 3292ce0 commit 7600713
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 0 deletions.
6 changes: 6 additions & 0 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2082,6 +2082,12 @@ example:
function call, use of ``longjmp``, or other means. It is a compiler hint that
is used at module level to improve dataflow analysis, dropped during linking,
and has no effect on functions defined in the current module.
``nodivergencesource``
A call to this function is not a source of divergence. In uniformity
analysis, a *source of divergence* is an instruction that generates
divergence even if its inputs are uniform. A call with no further information
would normally be considered a source of divergence; setting this attribute
on a function means that a call to it is not a source of divergence.
``noduplicate``
This attribute indicates that calls to the function cannot be
duplicated. A call to a ``noduplicate`` function may be moved
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ enum AttributeKindCodes {
ATTR_KIND_SANITIZE_REALTIME_UNSAFE = 97,
ATTR_KIND_CORO_ELIDE_SAFE = 98,
ATTR_KIND_NO_EXT = 99,
ATTR_KIND_NO_DIVERGENCE_SOURCE = 100,
};

enum ComdatSelectionKindCodes {
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/Attributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ def NoCallback : EnumAttr<"nocallback", IntersectAnd, [FnAttr]>;
/// Function creates no aliases of pointer.
def NoCapture : EnumAttr<"nocapture", IntersectAnd, [ParamAttr]>;

/// Function is not a source of divergence.
def NoDivergenceSource : EnumAttr<"nodivergencesource", IntersectAnd, [FnAttr]>;

/// Call cannot be duplicated.
def NoDuplicate : EnumAttr<"noduplicate", IntersectPreserve, [FnAttr]>;

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Analysis/TargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,10 @@ bool TargetTransformInfo::hasBranchDivergence(const Function *F) const {
}

bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const {
if (const auto *Call = dyn_cast<CallBase>(V)) {
if (Call->hasFnAttr(Attribute::NoDivergenceSource))
return false;
}
return TTIImpl->isSourceOfDivergence(V);
}

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2066,6 +2066,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::NoCallback;
case bitc::ATTR_KIND_NO_CAPTURE:
return Attribute::NoCapture;
case bitc::ATTR_KIND_NO_DIVERGENCE_SOURCE:
return Attribute::NoDivergenceSource;
case bitc::ATTR_KIND_NO_DUPLICATE:
return Attribute::NoDuplicate;
case bitc::ATTR_KIND_NOFREE:
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_NO_CALLBACK;
case Attribute::NoCapture:
return bitc::ATTR_KIND_NO_CAPTURE;
case Attribute::NoDivergenceSource:
return bitc::ATTR_KIND_NO_DIVERGENCE_SOURCE;
case Attribute::NoDuplicate:
return bitc::ATTR_KIND_NO_DUPLICATE;
case Attribute::NoFree:
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/Utils/CodeExtractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::NoFPClass:
case Attribute::CoroDestroyOnlyWhenComplete:
case Attribute::CoroElideSafe:
case Attribute::NoDivergenceSource:
continue;
// Those attributes should be safe to propagate to the extracted function.
case Attribute::AlwaysInline:
Expand Down
16 changes: 16 additions & 0 deletions llvm/test/Analysis/UniformityAnalysis/AMDGPU/nodivergencesource.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; RUN: opt -mtriple amdgcn-- -passes='print<uniformity>' -disable-output %s 2>&1 | FileCheck %s

; CHECK: DIVERGENT: %divergentval
; CHECK-NOT: DIVERGENT: %uniformval
; CHECK: %uniformval
define void @test() {
%divergentval = call i32 @normalfunc()
%uniformval = call i32 @nodivergencesourcefunc()
ret void
}

declare i32 @normalfunc() #0
declare i32 @nodivergencesourcefunc() #1

attributes #0 = { nounwind }
attributes #1 = { nounwind nodivergencesource }
6 changes: 6 additions & 0 deletions llvm/test/Bitcode/attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,11 @@ define void @f91(ptr dead_on_unwind %p) {
ret void
}

; CHECK: define void @f94() [[NODIVERGENCESOURCE:#[0-9]+]]
define void @f94() nodivergencesource {
ret void;
}

; CHECK: define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a)
define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a) {
ret i32 0
Expand Down Expand Up @@ -615,4 +620,5 @@ define void @initializes(ptr initializes((-4, 0), (4, 8)) %a) {
; CHECK: attributes [[FNRETTHUNKEXTERN]] = { fn_ret_thunk_extern }
; CHECK: attributes [[SKIPPROFILE]] = { skipprofile }
; CHECK: attributes [[OPTDEBUG]] = { optdebug }
; CHECK: attributes [[NODIVERGENCESOURCE]] = { nodivergencesource }
; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin }

0 comments on commit 7600713

Please sign in to comment.