diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h index 4398377606636..88a1837665aab 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -61,7 +61,8 @@ class CallLowering { 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"); } diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp index f6daa5f7f9e2f..9f37efc0951b0 100644 --- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -237,13 +237,13 @@ void AArch64CallLowering::splitToValueTypes( const AArch64TargetLowering &TLI = *getTLI(); LLVMContext &Ctx = OrigArg.Ty->getContext(); - if (OrigArg.Ty->isVoidTy()) - return; - SmallVector SplitVTs; 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). diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll index e60360fdee684..ad38b2bb8b9c2 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll @@ -279,3 +279,45 @@ define void @take_split_struct([2 x i64]* %ptr, i64, i64, i64, 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 +}