Navigation Menu

Skip to content

Commit

Permalink
[AMDGPU] Fix function pointer argument bug in AMDGPU Propagate Attrib…
Browse files Browse the repository at this point in the history
…utes pass.

This patch fixes a bug in the AMDGPU Propagate Attributes pass where a call
instruction with a function pointer argument is identified as a user of the
passed function, and illegally replaces the called function of the
instruction with the function argument.

For example, given functions f and g with appropriate types, the following
illegal transformation could occur without this fix:
call void @f(void ()* @g)
-->
call void @g(void ()* @g.1)

The solution introduced in this patch is to prevent the cloning and
substitution if the instruction's called function and the function which
might be cloned do not match.

Reviewed By: arsenm, madhur13490

Differential Revision: https://reviews.llvm.org/D101847
  • Loading branch information
jweightma authored and Flakebi committed May 26, 2021
1 parent b37a2fc commit fcd32d6
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
6 changes: 5 additions & 1 deletion llvm/lib/Target/AMDGPU/AMDGPUPropagateAttributes.cpp
Expand Up @@ -249,7 +249,11 @@ bool AMDGPUPropagateAttributes::process() {
if (!I)
continue;
CallBase *CI = dyn_cast<CallBase>(I);
if (!CI)
// Only propagate attributes if F is the called function. Specifically,
// do not propagate attributes if F is passed as an argument.
// FIXME: handle bitcasted callee, e.g.
// %retval = call i8* bitcast (i32* ()* @f to i8* ()*)()
if (!CI || CI->getCalledOperand() != &F)
continue;
Function *Caller = CI->getCaller();
if (!Caller || !Visited.insert(CI).second)
Expand Down
@@ -0,0 +1,40 @@
; This is a regression test for a bug in the AMDGPU Propagate Attributes pass
; where a call instruction's callee could be replaced with a function pointer
; passed to the original call instruction as an argument.
;
; Example:
; `call void @f(void ()* @g)`
; could become
; `call void @g(void ()* @g.1)`
; which is invalid IR.

; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-propagate-attributes-late %s | FileCheck %s

; CHECK-LABEL: define amdgpu_kernel void @thiswasabug() #0
; CHECK-NOT: call void @g(void ()* @g.1)
; CHECK-DAG: call void @f(void ()* @g.1)
; CHECK-DAG: call void @g()
define amdgpu_kernel void @thiswasabug() #0 {
; no replacement, but @g should be renamed to @g.1
call void @f(void ()* @g)

; this should call the clone, which takes the name @g
call void @g()
ret void
}

define private void @f(void ()* nocapture %0) #0 {
ret void
}

; In order to expose this bug, it is necessary that `g` have one of the
; propagated attributes, so that a clone and substitution would take place if g
; were actually the function being called.
; CHECK-DAG: define private void @g.1() #1
; CHECK-DAG: define internal void @g() #2
define private void @g() #1 {
ret void
}

attributes #0 = { noinline }
attributes #1 = { noinline "amdgpu-waves-per-eu"="1,10" }

0 comments on commit fcd32d6

Please sign in to comment.