在C ++中,我们可以让内联asm返回2个值,如:
ulonglong2 ThreadLoad<cub_modifier, ulonglong2*>(ulonglong2* ptr)
{
ulonglong2 retval;
asm volatile ("ld."#ptx_modifier".v2.u64 {%0, %1}, [%2];"
"=l"(retval.x),
"=l"(retval.y) :
_CUB_ASM_PTR_(ptr));
return retval;
}
我们如何为此用途创建LLVM IR?我试过了:
%3 = alloca { i32, i32 }, align 8
%40 = getelementptr inbounds { i32, i32 }* %38, i64 %39
%41 = getelementptr inbounds { i32, i32 }* %3, i32 0, i32 0
%42 = getelementptr inbounds { i32, i32 }* %3, i32 0, i32 1
call void asm sideeffect alignstack "ld.cg.v2.u32 \09{$0, $1}, [$2];", "=l,=l,l"(i32* %41, i32* %42, { i32, i32 }* %40)
%43 = load { i32, i32 }* %3, align 8
这不起作用。
答案 0 :(得分:1)
我为你的问题做了一个玩具示例:
struct ulonglong2
{
unsigned long long x;
unsigned long long y;
};
ulonglong2 ThreadLoad(ulonglong2* ptr)
{
ulonglong2 retval;
asm volatile ("ld.cg.v2.u64 {%0, %1}, [%2];" : "=l"(retval.x), "=l"(retval.y) : "l" (ptr));
return retval;
}
int main() {
ulonglong2 val;
ulonglong2 x = ThreadLoad(&val);
return 0;
}
让clang发出LLVM IR(命令:clang -emit-llvm test.cpp -c -S -o ptx.ll
):
; Function Attrs: nounwind uwtable
define { i64, i64 } @_Z10ThreadLoadP10ulonglong2(%struct.ulonglong2* %ptr) #0 {
%1 = alloca %struct.ulonglong2, align 8
%2 = alloca %struct.ulonglong2*, align 8
store %struct.ulonglong2* %ptr, %struct.ulonglong2** %2, align 8
%3 = getelementptr inbounds %struct.ulonglong2* %1, i32 0, i32 0
%4 = getelementptr inbounds %struct.ulonglong2* %1, i32 0, i32 1
%5 = load %struct.ulonglong2** %2, align 8
%6 = call { i64, i64 } asm sideeffect "ld.cg.v2.u64 $($0, $1$), [$2];", "=l,=l,l,~{dirflag},~{fpsr},~{flags}"(%struct.ulonglong2* %5) #1, !srcloc !1
%7 = extractvalue { i64, i64 } %6, 0
%8 = extractvalue { i64, i64 } %6, 1
store i64 %7, i64* %3, align 8
store i64 %8, i64* %4, align 8
%9 = bitcast %struct.ulonglong2* %1 to { i64, i64 }*
%10 = load { i64, i64 }* %9, align 1
ret { i64, i64 } %10
}
相关的一条线:
%6 = call { i64, i64 } asm sideeffect "ld.cg.v2.u64 $($0, $1$), [$2];", "=l,=l,l,~{dirflag},~{fpsr},~{flags}"(%struct.ulonglong2* %5) #1, !srcloc !1
你的asm调用需要{i64, i64}
作为返回类型,只需要一个输入参数(因为你只在你的asm行中声明一个)。其他一切都是向前发展的。获取指针存储两个ulonglong
值的位置并存储它。 %9
之后的所有内容只是将值作为结构返回。如果您将-O3
传递给clang,您将看到除了asm调用之外的所有内容都会消失,并且指针会直接转发到asm调用。