diff --git a/lib/Target/ARM/ARMCallLowering.cpp b/lib/Target/ARM/ARMCallLowering.cpp index a827fd9de19..4731cbbe0f0 100644 --- a/lib/Target/ARM/ARMCallLowering.cpp +++ b/lib/Target/ARM/ARMCallLowering.cpp @@ -57,8 +57,7 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler { unsigned getStackAddress(uint64_t Size, int64_t Offset, MachinePointerInfo &MPO) override { - // FIXME: Support smaller sizes (which may require extensions). - assert((Size == 4 || Size == 8) && "Unsupported size"); + assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) && "Unsupported size"); LLT p0 = LLT::pointer(0, 32); LLT s32 = LLT::scalar(32); @@ -72,7 +71,6 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler { MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg); MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset); - StackSize = std::max(StackSize, Size + Offset); return AddrReg; } @@ -91,12 +89,14 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler { void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, MachinePointerInfo &MPO, CCValAssign &VA) override { - // FIXME: Support smaller sizes (which may require extensions). - assert((Size == 4 || Size == 8) && "Unsupported size"); + assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) && + "Unsupported size"); + unsigned ExtReg = extendRegister(ValVReg, VA); auto MMO = MIRBuilder.getMF().getMachineMemOperand( - MPO, MachineMemOperand::MOStore, Size, /* Alignment */ 0); - MIRBuilder.buildStore(ValVReg, Addr, *MMO); + MPO, MachineMemOperand::MOStore, VA.getLocVT().getStoreSize(), + /* Alignment */ 0); + MIRBuilder.buildStore(ExtReg, Addr, *MMO); } unsigned assignCustomValue(const CallLowering::ArgInfo &Arg, @@ -130,6 +130,17 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler { return 1; } + bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, const CallLowering::ArgInfo &Info, + CCState &State) override { + if (AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State)) + return true; + + StackSize = std::max(StackSize, + static_cast(State.getNextStackOffset())); + return false; + } + MachineInstrBuilder &MIB; uint64_t StackSize; }; diff --git a/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll b/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll index c7a5a6cb67b..972a2791456 100644 --- a/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll +++ b/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll @@ -392,11 +392,11 @@ define arm_aapcscc i32* @test_call_simple_stack_params(i32 *%a, i32 %b) { ; CHECK: [[SP1:%[0-9]+]](p0) = COPY %sp ; CHECK: [[OFF1:%[0-9]+]](s32) = G_CONSTANT i32 0 ; CHECK: [[FI1:%[0-9]+]](p0) = G_GEP [[SP1]], [[OFF1]](s32) -; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0) +; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store 4 ; CHECK: [[SP2:%[0-9]+]](p0) = COPY %sp ; CHECK: [[OFF2:%[0-9]+]](s32) = G_CONSTANT i32 4 ; CHECK: [[FI2:%[0-9]+]](p0) = G_GEP [[SP2]], [[OFF2]](s32) -; CHECK: G_STORE [[AVREG]](p0), [[FI2]](p0) +; CHECK: G_STORE [[AVREG]](p0), [[FI2]](p0){{.*}}store 4 ; CHECK: BLX @simple_stack_params_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r1, implicit %r2, implicit %r3, implicit-def %r0 ; CHECK: [[RVREG:%[0-9]+]](p0) = COPY %r0 ; CHECK: ADJCALLSTACKUP 8, 0, 14, _, implicit-def %sp, implicit %sp @@ -407,29 +407,55 @@ entry: ret i32 *%r } -declare arm_aapcscc signext i16 @ext_target(i8 signext, i8 zeroext, i16 signext, i16 zeroext) +declare arm_aapcscc signext i16 @ext_target(i8 signext, i8 zeroext, i16 signext, i16 zeroext, i8 signext, i8 zeroext, i16 signext, i16 zeroext, i1 zeroext) -define arm_aapcscc signext i16 @test_call_ext_params(i8 %a, i16 %b) { +define arm_aapcscc signext i16 @test_call_ext_params(i8 %a, i16 %b, i1 %c) { ; CHECK-LABEL: name: test_call_ext_params ; CHECK-DAG: [[AVREG:%[0-9]+]](s8) = COPY %r0 ; CHECK-DAG: [[BVREG:%[0-9]+]](s16) = COPY %r1 -; CHECK: ADJCALLSTACKDOWN 0, 14, _, implicit-def %sp, implicit %sp -; CHECK-DAG: [[SEXTA:%[0-9]+]](s32) = G_SEXT [[AVREG]](s8) -; CHECK-DAG: %r0 = COPY [[SEXTA]] -; CHECK-DAG: [[ZEXTA:%[0-9]+]](s32) = G_ZEXT [[AVREG]](s8) -; CHECK-DAG: %r1 = COPY [[ZEXTA]] -; CHECK-DAG: [[SEXTB:%[0-9]+]](s32) = G_SEXT [[BVREG]](s16) -; CHECK-DAG: %r2 = COPY [[SEXTB]] -; CHECK-DAG: [[ZEXTB:%[0-9]+]](s32) = G_ZEXT [[BVREG]](s16) -; CHECK-DAG: %r3 = COPY [[ZEXTB]] +; CHECK-DAG: [[CVREG:%[0-9]+]](s1) = COPY %r2 +; CHECK: ADJCALLSTACKDOWN 20, 14, _, implicit-def %sp, implicit %sp +; CHECK: [[SEXTA:%[0-9]+]](s32) = G_SEXT [[AVREG]](s8) +; CHECK: %r0 = COPY [[SEXTA]] +; CHECK: [[ZEXTA:%[0-9]+]](s32) = G_ZEXT [[AVREG]](s8) +; CHECK: %r1 = COPY [[ZEXTA]] +; CHECK: [[SEXTB:%[0-9]+]](s32) = G_SEXT [[BVREG]](s16) +; CHECK: %r2 = COPY [[SEXTB]] +; CHECK: [[ZEXTB:%[0-9]+]](s32) = G_ZEXT [[BVREG]](s16) +; CHECK: %r3 = COPY [[ZEXTB]] +; CHECK: [[SP1:%[0-9]+]](p0) = COPY %sp +; CHECK: [[OFF1:%[0-9]+]](s32) = G_CONSTANT i32 0 +; CHECK: [[FI1:%[0-9]+]](p0) = G_GEP [[SP1]], [[OFF1]](s32) +; CHECK: [[SEXTA2:%[0-9]+]](s32) = G_SEXT [[AVREG]] +; CHECK: G_STORE [[SEXTA2]](s32), [[FI1]](p0){{.*}}store 4 +; CHECK: [[SP2:%[0-9]+]](p0) = COPY %sp +; CHECK: [[OFF2:%[0-9]+]](s32) = G_CONSTANT i32 4 +; CHECK: [[FI2:%[0-9]+]](p0) = G_GEP [[SP2]], [[OFF2]](s32) +; CHECK: [[ZEXTA2:%[0-9]+]](s32) = G_ZEXT [[AVREG]] +; CHECK: G_STORE [[ZEXTA2]](s32), [[FI2]](p0){{.*}}store 4 +; CHECK: [[SP3:%[0-9]+]](p0) = COPY %sp +; CHECK: [[OFF3:%[0-9]+]](s32) = G_CONSTANT i32 8 +; CHECK: [[FI3:%[0-9]+]](p0) = G_GEP [[SP3]], [[OFF3]](s32) +; CHECK: [[SEXTB2:%[0-9]+]](s32) = G_SEXT [[BVREG]] +; CHECK: G_STORE [[SEXTB2]](s32), [[FI3]](p0){{.*}}store 4 +; CHECK: [[SP4:%[0-9]+]](p0) = COPY %sp +; CHECK: [[OFF4:%[0-9]+]](s32) = G_CONSTANT i32 12 +; CHECK: [[FI4:%[0-9]+]](p0) = G_GEP [[SP4]], [[OFF4]](s32) +; CHECK: [[ZEXTB2:%[0-9]+]](s32) = G_ZEXT [[BVREG]] +; CHECK: G_STORE [[ZEXTB2]](s32), [[FI4]](p0){{.*}}store 4 +; CHECK: [[SP5:%[0-9]+]](p0) = COPY %sp +; CHECK: [[OFF5:%[0-9]+]](s32) = G_CONSTANT i32 16 +; CHECK: [[FI5:%[0-9]+]](p0) = G_GEP [[SP5]], [[OFF5]](s32) +; CHECK: [[ZEXTC:%[0-9]+]](s32) = G_ZEXT [[CVREG]] +; CHECK: G_STORE [[ZEXTC]](s32), [[FI5]](p0){{.*}}store 4 ; CHECK: BLX @ext_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r1, implicit %r2, implicit %r3, implicit-def %r0 ; CHECK: [[RVREG:%[0-9]+]](s16) = COPY %r0 -; CHECK: ADJCALLSTACKUP 0, 0, 14, _, implicit-def %sp, implicit %sp +; CHECK: ADJCALLSTACKUP 20, 0, 14, _, implicit-def %sp, implicit %sp ; CHECK: [[RExtVREG:%[0-9]+]](s32) = G_SEXT [[RVREG]] ; CHECK: %r0 = COPY [[RExtVREG]] ; CHECK: BX_RET 14, _, implicit %r0 entry: - %r = notail call arm_aapcscc signext i16 @ext_target(i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b) + %r = notail call arm_aapcscc signext i16 @ext_target(i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b, i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b, i1 zeroext %c) ret i16 %r } @@ -471,11 +497,11 @@ define arm_aapcscc double @test_call_aapcs_fp_params(double %a, float %b) { ; CHECK: [[SP1:%[0-9]+]](p0) = COPY %sp ; CHECK: [[OFF1:%[0-9]+]](s32) = G_CONSTANT i32 0 ; CHECK: [[FI1:%[0-9]+]](p0) = G_GEP [[SP1]], [[OFF1]](s32) -; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0) +; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store 4 ; CHECK: [[SP2:%[0-9]+]](p0) = COPY %sp ; CHECK: [[OFF2:%[0-9]+]](s32) = G_CONSTANT i32 8 ; CHECK: [[FI2:%[0-9]+]](p0) = G_GEP [[SP2]], [[OFF2]](s32) -; CHECK: G_STORE [[AVREG]](s64), [[FI2]](p0) +; CHECK: G_STORE [[AVREG]](s64), [[FI2]](p0){{.*}}store 8 ; CHECK: BLX @aapcscc_fp_target, csr_aapcs, implicit-def %lr, implicit %sp, implicit %r0, implicit %r2, implicit %r3, implicit-def %r0, implicit-def %r1 ; CHECK-DAG: [[R1:%[0-9]+]](s32) = COPY %r0 ; CHECK-DAG: [[R2:%[0-9]+]](s32) = COPY %r1