[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