Index: llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h =================================================================== --- llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -61,7 +61,8 @@ if (!Regs.empty() && Flags.empty()) this->Flags.push_back(ISD::ArgFlagsTy()); // FIXME: We should have just one way of saying "no register". - assert((Ty->isVoidTy() == (Regs.empty() || Regs[0] == 0)) && + assert(((Ty->isVoidTy() || Ty->isEmptyTy()) == + (Regs.empty() || Regs[0] == 0)) && "only void types should have no register"); } Index: llvm/lib/Target/AArch64/AArch64CallLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -244,6 +244,9 @@ SmallVector Offsets; ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); + if (SplitVTs.size() == 0) + return; + if (SplitVTs.size() == 1) { // No splitting to do, but we want to replace the original type (e.g. [1 x // double] -> double). Index: llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll =================================================================== --- llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll +++ llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll @@ -279,3 +279,45 @@ store [2 x i64] %in, [2 x i64]* %ptr ret void } + +%size0type = type { } +declare %size0type @func.returns.size0.struct() + +; CHECK-LABEL: name: call_returns_size0_struct +; CHECK: bb.1 +; CHECK-NEXT: ADJCALLSTACKDOWN +; CHECK-NEXT: BL +; CHECK-NEXT: ADJCALLSTACKUP +; CHECK-NEXT: RET_ReallyLR +define void @call_returns_size0_struct() { + ; FIXME: Why is this valid IR? + %call = call %size0type @func.returns.size0.struct() + ret void +} + +declare [0 x i8] @func.returns.size0.array() + +; CHECK-LABEL: name: call_returns_size0_array +; CHECK: bb.1 +; CHECK-NEXT: ADJCALLSTACKDOWN +; CHECK-NEXT: BL +; CHECK-NEXT: ADJCALLSTACKUP +; CHECK-NEXT: RET_ReallyLR +define void @call_returns_size0_array() { + ; FIXME: Why is this valid IR? + %call = call [0 x i8] @func.returns.size0.array() + ret void +} + +declare [1 x %size0type] @func.returns.array.size0.struct() +; CHECK-LABEL: name: call_returns_array_size0_struct +; CHECK: bb.1 +; CHECK-NEXT: ADJCALLSTACKDOWN +; CHECK-NEXT: BL +; CHECK-NEXT: ADJCALLSTACKUP +; CHECK-NEXT: RET_ReallyLR +define void @call_returns_array_size0_struct() { + ; FIXME: Why is this valid IR? + %call = call [1 x %size0type] @func.returns.array.size0.struct() + ret void +}