1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[AMDGPU] Fix function pointer argument bug in AMDGPU Propagate Attributes 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
This commit is contained in:
jweightma 2021-05-26 16:33:33 +02:00 committed by Sebastian Neubauer
parent f106aa368d
commit b8e979ccdd
2 changed files with 45 additions and 1 deletions

View File

@ -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)

View File

@ -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" }