[llvm] 224a8c6 - [GlobalISel][CallLowering] Look through call parameters for flags
Jessica Paquette via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 08:59:55 PDT 2020
Author: Jessica Paquette
Date: 2020-08-18T08:48:56-07:00
New Revision: 224a8c639eeb36b7a5ac6f8a50295f9ee2cb2518
URL: https://github.com/llvm/llvm-project/commit/224a8c639eeb36b7a5ac6f8a50295f9ee2cb2518
DIFF: https://github.com/llvm/llvm-project/commit/224a8c639eeb36b7a5ac6f8a50295f9ee2cb2518.diff
LOG: [GlobalISel][CallLowering] Look through call parameters for flags
We weren't looking through the parameters on calls at all.
E.g., say you had
```
declare i32 @zext(i32 zeroext %x)
...
%y = call i32 @zext(i32 %something)
...
```
At the point of the call, we wouldn't know that the %something should have the
zeroext attribute.
This sets flags in about the same way as
TargetLoweringBase::ArgListEntry::setAttributes.
Differential Revision: https://reviews.llvm.org/D86125
Added:
Modified:
llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll
llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
index 38afed764f29..1eec08f51062 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
@@ -208,6 +208,11 @@ class CallLowering {
return static_cast<const XXXTargetLowering *>(TLI);
}
+ /// \returns Flags corresponding to the attributes on the \p ArgIdx-th
+ /// parameter of \p Call.
+ ISD::ArgFlagsTy getAttributesForArgIdx(const CallBase &Call,
+ unsigned ArgIdx) const;
+
template <typename FuncInfoTy>
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL,
const FuncInfoTy &FuncInfo) const;
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index 661a8560a1c9..e443f603def6 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -30,6 +30,34 @@ using namespace llvm;
void CallLowering::anchor() {}
+ISD::ArgFlagsTy CallLowering::getAttributesForArgIdx(const CallBase &Call,
+ unsigned ArgIdx) const {
+ ISD::ArgFlagsTy Flags;
+ if (Call.paramHasAttr(ArgIdx, Attribute::SExt))
+ Flags.setSExt();
+ if (Call.paramHasAttr(ArgIdx, Attribute::ZExt))
+ Flags.setZExt();
+ if (Call.paramHasAttr(ArgIdx, Attribute::InReg))
+ Flags.setInReg();
+ if (Call.paramHasAttr(ArgIdx, Attribute::StructRet))
+ Flags.setSRet();
+ if (Call.paramHasAttr(ArgIdx, Attribute::Nest))
+ Flags.setNest();
+ if (Call.paramHasAttr(ArgIdx, Attribute::ByVal))
+ Flags.setByVal();
+ if (Call.paramHasAttr(ArgIdx, Attribute::Preallocated))
+ Flags.setPreallocated();
+ if (Call.paramHasAttr(ArgIdx, Attribute::InAlloca))
+ Flags.setInAlloca();
+ if (Call.paramHasAttr(ArgIdx, Attribute::Returned))
+ Flags.setReturned();
+ if (Call.paramHasAttr(ArgIdx, Attribute::SwiftSelf))
+ Flags.setSwiftSelf();
+ if (Call.paramHasAttr(ArgIdx, Attribute::SwiftError))
+ Flags.setSwiftError();
+ return Flags;
+}
+
bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB,
ArrayRef<Register> ResRegs,
ArrayRef<ArrayRef<Register>> ArgRegs,
@@ -44,7 +72,7 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB,
unsigned i = 0;
unsigned NumFixedArgs = CB.getFunctionType()->getNumParams();
for (auto &Arg : CB.args()) {
- ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{},
+ ArgInfo OrigArg{ArgRegs[i], Arg->getType(), getAttributesForArgIdx(CB, i),
i < NumFixedArgs};
setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, CB);
Info.OrigArgs.push_back(OrigArg);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
index ad38b2bb8b9c..7eb21c21b86c 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
@@ -151,6 +151,42 @@ define void @test_abi_exts_call(i8* %addr) {
ret void
}
+; CHECK-LABEL: name: test_zext_in_callee
+; CHECK: bb.1 (%ir-block.0):
+; CHECK: liveins: $x0
+; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+; CHECK: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load 1 from %ir.addr)
+; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[LOAD]](s8)
+; CHECK: $w0 = COPY [[ZEXT]](s32)
+; CHECK: BL @has_zext_param, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0
+; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+; CHECK: RET_ReallyLR
+declare void @has_zext_param(i8 zeroext)
+define void @test_zext_in_callee(i8* %addr) {
+ %val = load i8, i8* %addr
+ call void @has_zext_param(i8 %val)
+ ret void
+}
+
+; CHECK-LABEL: name: test_sext_in_callee
+; CHECK: bb.1 (%ir-block.0):
+; CHECK: liveins: $x0
+; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+; CHECK: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load 1 from %ir.addr)
+; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
+; CHECK: [[SEXT:%[0-9]+]]:_(s32) = G_SEXT [[LOAD]](s8)
+; CHECK: $w0 = COPY [[SEXT]](s32)
+; CHECK: BL @has_sext_param, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $w0
+; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
+; CHECK: RET_ReallyLR
+declare void @has_sext_param(i8 signext)
+define void @test_sext_in_callee(i8* %addr) {
+ %val = load i8, i8* %addr
+ call void @has_sext_param(i8 %val)
+ ret void
+}
+
; CHECK-LABEL: name: test_abi_sext_ret
; CHECK: [[VAL:%[0-9]+]]:_(s8) = G_LOAD
; CHECK: [[SVAL:%[0-9]+]]:_(s32) = G_SEXT [[VAL]](s8)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll b/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
index 4a3e5b046814..a4a1747b05af 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll
@@ -513,3 +513,67 @@ a:
%error = load %swift_error*, %swift_error** %error_ptr
ret %swift_error* %error
}
+
+; foo takes a swifterror parameter. We should be able to see that even when
+; it isn't explicitly on the call.
+define float @swifterror_param_not_on_call(i8* %error_ref) {
+; CHECK-LABEL: swifterror_param_not_on_call:
+; CHECK: mov [[ID:x[0-9]+]], x0
+; CHECK: bl {{.*}}foo
+; CHECK: mov x0, x21
+; CHECK: cbnz x21
+; Access part of the error object and save it to error_ref
+; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]
+; CHECK: strb [[CODE]], [{{.*}}[[ID]]]
+; CHECK: bl {{.*}}free
+
+entry:
+ %error_ptr_ref = alloca swifterror %swift_error*
+ store %swift_error* null, %swift_error** %error_ptr_ref
+ %call = call float @foo(%swift_error** %error_ptr_ref)
+ %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
+ %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
+ %tmp = bitcast %swift_error* %error_from_foo to i8*
+ br i1 %had_error_from_foo, label %handler, label %cont
+cont:
+ %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
+ %t = load i8, i8* %v1
+ store i8 %t, i8* %error_ref
+ br label %handler
+handler:
+ call void @free(i8* %tmp)
+ ret float 1.0
+}
+
+; foo_sret takes an sret parameter and a swifterror parameter. We should be
+; able to see that, even if it's not explicitly on the call.
+define float @swifterror_param_not_on_call2(i8* %error_ref) {
+; CHECK-LABEL: swifterror_param_not_on_call2:
+; CHECK: mov [[ID:x[0-9]+]], x0
+; CHECK: mov [[ZERO:x[0-9]+]], xzr
+; CHECK: bl {{.*}}foo_sret
+; CHECK: mov x0, x21
+; CHECK: cbnz x21
+; Access part of the error object and save it to error_ref
+; CHECK: ldrb [[CODE:w[0-9]+]], [x0, #8]
+; CHECK: strb [[CODE]], [{{.*}}[[ID]]]
+; CHECK: bl {{.*}}free
+
+entry:
+ %s = alloca %struct.S, align 8
+ %error_ptr_ref = alloca swifterror %swift_error*
+ store %swift_error* null, %swift_error** %error_ptr_ref
+ call void @foo_sret(%struct.S* %s, i32 1, %swift_error** %error_ptr_ref)
+ %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
+ %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
+ %tmp = bitcast %swift_error* %error_from_foo to i8*
+ br i1 %had_error_from_foo, label %handler, label %cont
+cont:
+ %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
+ %t = load i8, i8* %v1
+ store i8 %t, i8* %error_ref
+ br label %handler
+handler:
+ call void @free(i8* %tmp)
+ ret float 1.0
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll b/llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll
index 8ed06f23383c..0f090d488cf1 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/swiftself.ll
@@ -60,3 +60,14 @@ entry:
store i8* %3, i8** %0, align 8
ret void
}
+
+; Check that x20 is used to pass a swiftself argument when the parameter is
+; only in the declaration's arguments.
+; CHECK-LABEL: _swiftself_not_on_call_params:
+; CHECK: mov x20, x0
+; CHECK: bl {{_?}}swiftself_param
+; CHECK: ret
+define i8 *@swiftself_not_on_call_params(i8* %arg) {
+ %res = call i8 *@swiftself_param(i8* %arg)
+ ret i8 *%res
+}
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll
index d53cfe688f53..f244a840476d 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/irtranslator-call-sret.ll
@@ -49,9 +49,12 @@ define amdgpu_kernel void @test_call_external_void_func_sret_struct_i8_i32_byval
; GCN: [[SHL1:%[0-9]+]]:_(s32) = G_SHL [[COPY20]], [[C5]](s32)
; GCN: [[OR1:%[0-9]+]]:_(s32) = G_OR [[OR]], [[SHL1]]
; GCN: $vgpr0 = COPY [[FRAME_INDEX1]](p5)
- ; GCN: $vgpr1 = COPY [[FRAME_INDEX]](p5)
- ; GCN: [[COPY21:%[0-9]+]]:_(<4 x s32>) = COPY $private_rsrc_reg
- ; GCN: $sgpr0_sgpr1_sgpr2_sgpr3 = COPY [[COPY21]](<4 x s32>)
+ ; GCN: [[COPY21:%[0-9]+]]:_(p5) = COPY $sp_reg
+ ; GCN: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; GCN: [[PTR_ADD2:%[0-9]+]]:_(p5) = G_PTR_ADD [[COPY21]], [[C6]](s32)
+ ; GCN: G_STORE [[FRAME_INDEX]](p5), [[PTR_ADD2]](p5) :: (store 4 into stack, align 16, addrspace 5)
+ ; GCN: [[COPY22:%[0-9]+]]:_(<4 x s32>) = COPY $private_rsrc_reg
+ ; GCN: $sgpr0_sgpr1_sgpr2_sgpr3 = COPY [[COPY22]](<4 x s32>)
; GCN: $sgpr4_sgpr5 = COPY [[COPY11]](p4)
; GCN: $sgpr6_sgpr7 = COPY [[COPY12]](p4)
; GCN: $sgpr8_sgpr9 = COPY [[PTR_ADD1]](p4)
@@ -60,11 +63,11 @@ define amdgpu_kernel void @test_call_external_void_func_sret_struct_i8_i32_byval
; GCN: $sgpr13 = COPY [[COPY16]](s32)
; GCN: $sgpr14 = COPY [[COPY17]](s32)
; GCN: $vgpr31 = COPY [[OR1]](s32)
- ; GCN: $sgpr30_sgpr31 = SI_CALL [[GV]](p0), @external_void_func_sret_struct_i8_i32_byval_struct_i8_i32, csr_amdgpu_highregs, implicit $vgpr0, implicit $vgpr1, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr4_sgpr5, implicit $sgpr6_sgpr7, implicit $sgpr8_sgpr9, implicit $sgpr10_sgpr11, implicit $sgpr12, implicit $sgpr13, implicit $sgpr14, implicit $vgpr31
- ; GCN: ADJCALLSTACKDOWN 0, 0, implicit-def $scc
- ; GCN: [[PTR_ADD2:%[0-9]+]]:_(p5) = G_PTR_ADD [[FRAME_INDEX1]], [[C2]](s32)
+ ; GCN: $sgpr30_sgpr31 = SI_CALL [[GV]](p0), @external_void_func_sret_struct_i8_i32_byval_struct_i8_i32, csr_amdgpu_highregs, implicit $vgpr0, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr4_sgpr5, implicit $sgpr6_sgpr7, implicit $sgpr8_sgpr9, implicit $sgpr10_sgpr11, implicit $sgpr12, implicit $sgpr13, implicit $sgpr14, implicit $vgpr31
+ ; GCN: ADJCALLSTACKDOWN 0, 8, implicit-def $scc
+ ; GCN: [[PTR_ADD3:%[0-9]+]]:_(p5) = G_PTR_ADD [[FRAME_INDEX1]], [[C2]](s32)
; GCN: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[FRAME_INDEX1]](p5) :: (dereferenceable load 1 from %ir.out.gep02, addrspace 5)
- ; GCN: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD2]](p5) :: (dereferenceable load 4 from %ir.out.gep1, addrspace 5)
+ ; GCN: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD3]](p5) :: (dereferenceable load 4 from %ir.out.gep1, addrspace 5)
; GCN: G_STORE [[LOAD]](s8), [[DEF]](p1) :: (volatile store 1 into `i8 addrspace(1)* undef`, addrspace 1)
; GCN: G_STORE [[LOAD1]](s32), [[COPY10]](p1) :: (volatile store 4 into `i32 addrspace(1)* undef`, addrspace 1)
; GCN: S_ENDPGM 0
More information about the llvm-commits
mailing list