15 changes: 8 additions & 7 deletions llvm/lib/Target/AArch64/AArch64CallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,13 @@ struct OutgoingArgHandler : public CallLowering::ValueHandler {
bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
CCValAssign::LocInfo LocInfo,
const CallLowering::ArgInfo &Info,
ISD::ArgFlagsTy Flags,
CCState &State) override {
bool Res;
if (Info.IsFixed)
Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State);
else
Res = AssignFnVarArg(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
Res = AssignFnVarArg(ValNo, ValVT, LocVT, LocInfo, Flags, State);

StackSize = State.getNextStackOffset();
return Res;
Expand Down Expand Up @@ -208,7 +209,7 @@ void AArch64CallLowering::splitToValueTypes(
// No splitting to do, but we want to replace the original type (e.g. [1 x
// double] -> double).
SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
OrigArg.Flags, OrigArg.IsFixed);
OrigArg.Flags[0], OrigArg.IsFixed);
return;
}

Expand All @@ -219,13 +220,13 @@ void AArch64CallLowering::splitToValueTypes(
OrigArg.Ty, CallConv, false);
for (unsigned i = 0, e = SplitVTs.size(); i < e; ++i) {
Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx);
SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags,
SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags[0],
OrigArg.IsFixed);
if (NeedsRegBlock)
SplitArgs.back().Flags.setInConsecutiveRegs();
SplitArgs.back().Flags[0].setInConsecutiveRegs();
}

SplitArgs.back().Flags.setInConsecutiveRegsLast();
SplitArgs.back().Flags[0].setInConsecutiveRegsLast();
}

bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
Expand Down Expand Up @@ -419,7 +420,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
splitToValueTypes(OrigArg, SplitArgs, DL, MRI, Info.CallConv);
// AAPCS requires that we zero-extend i1 to 8 bits by the caller.
if (OrigArg.Ty->isIntegerTy(1))
SplitArgs.back().Flags.setZExt();
SplitArgs.back().Flags[0].setZExt();
}

// Find out which ABI gets to decide where things go.
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler {
bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
CCValAssign::LocInfo LocInfo,
const CallLowering::ArgInfo &Info,
ISD::ArgFlagsTy Flags,
CCState &State) override {
return AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
return AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State);
}
};

Expand Down
11 changes: 6 additions & 5 deletions llvm/lib/Target/ARM/ARMCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler {

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))
const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
CCState &State) override {
if (AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State))
return true;

StackSize =
Expand Down Expand Up @@ -199,7 +200,7 @@ void ARMCallLowering::splitToValueTypes(const ArgInfo &OrigArg,
if (SplitVTs.size() == 1) {
// Even if there is no splitting to do, we still want to replace the
// original type (e.g. pointer type -> integer).
auto Flags = OrigArg.Flags;
auto Flags = OrigArg.Flags[0];
unsigned OriginalAlignment = DL.getABITypeAlignment(OrigArg.Ty);
Flags.setOrigAlign(OriginalAlignment);
SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx),
Expand All @@ -211,7 +212,7 @@ void ARMCallLowering::splitToValueTypes(const ArgInfo &OrigArg,
for (unsigned i = 0, e = SplitVTs.size(); i != e; ++i) {
EVT SplitVT = SplitVTs[i];
Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
auto Flags = OrigArg.Flags;
auto Flags = OrigArg.Flags[0];

unsigned OriginalAlignment = DL.getABITypeAlignment(SplitTy);
Flags.setOrigAlign(OriginalAlignment);
Expand Down Expand Up @@ -547,7 +548,7 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &
if (!Arg.IsFixed)
IsVarArg = true;

if (Arg.Flags.isByVal())
if (Arg.Flags[0].isByVal())
return false;

splitToValueTypes(Arg, ArgInfos, MF);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/Mips/MipsCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
for (auto &Arg : Info.OrigArgs) {
if (!isSupportedType(Arg.Ty))
return false;
if (Arg.Flags.isByVal() || Arg.Flags.isSRet())
if (Arg.Flags[0].isByVal() || Arg.Flags[0].isSRet())
return false;
}

Expand Down Expand Up @@ -641,7 +641,7 @@ void MipsCallLowering::subTargetRegTypeForCallingConv(
F.getContext(), F.getCallingConv(), VT);

for (unsigned i = 0; i < NumRegs; ++i) {
ISD::ArgFlagsTy Flags = Arg.Flags;
ISD::ArgFlagsTy Flags = Arg.Flags[0];

if (i == 0)
Flags.setOrigAlign(TLI.getABIAlignmentForCallingConv(Arg.Ty, DL));
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Target/X86/X86CallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler {

bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
CCValAssign::LocInfo LocInfo,
const CallLowering::ArgInfo &Info, CCState &State) override {
bool Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags,
CCState &State) override {
bool Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State);
StackSize = State.getNextStackOffset();

static const MCPhysReg XMMArgRegs[] = {X86::XMM0, X86::XMM1, X86::XMM2,
Expand Down Expand Up @@ -405,7 +406,7 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
for (const auto &OrigArg : Info.OrigArgs) {

// TODO: handle not simple cases.
if (OrigArg.Flags.isByVal())
if (OrigArg.Flags[0].isByVal())
return false;

if (OrigArg.Regs.size() > 1)
Expand Down
37 changes: 36 additions & 1 deletion llvm/test/CodeGen/AArch64/GlobalISel/arm64-callingconv.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc -O0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
; RUN: llc -O0 -stop-after=irtranslator -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s

target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-linux-gnu"
Expand Down Expand Up @@ -96,3 +96,38 @@ define void @test_stack_ext_needed() {
call void @stack_ext_needed([8 x i64] undef, i8 signext 42)
ret void
}

; Check that we can lower incoming i128 types into constituent s64 gprs.
; CHECK-LABEL: name: callee_s128
; CHECK: liveins: $x0, $x1, $x2, $x3, $x4
; CHECK: [[A1_P1:%[0-9]+]]:_(s64) = COPY $x0
; CHECK: [[A1_P2:%[0-9]+]]:_(s64) = COPY $x1
; CHECK: [[A1_MERGE:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[A1_P1]](s64), [[A1_P2]](s64)
; CHECK: [[A2_P1:%[0-9]+]]:_(s64) = COPY $x2
; CHECK: [[A2_P2:%[0-9]+]]:_(s64) = COPY $x3
; CHECK: [[A2_MERGE:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[A2_P1]](s64), [[A2_P2]](s64)
; CHECK: G_STORE [[A2_MERGE]](s128)
define void @callee_s128(i128 %a, i128 %b, i128 *%ptr) {
store i128 %b, i128 *%ptr
ret void
}

; Check we can lower outgoing s128 arguments into s64 gprs.
; CHECK-LABEL: name: caller_s128
; CHECK: [[PTR:%[0-9]+]]:_(p0) = COPY $x0
; CHECK: [[LARGE_VAL:%[0-9]+]]:_(s128) = G_LOAD [[PTR]](p0)
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
; CHECK: [[A1_P1:%[0-9]+]]:_(s64), [[A1_P2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[LARGE_VAL]](s128)
; CHECK: [[A2_P1:%[0-9]+]]:_(s64), [[A2_P2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES %1(s128)
; CHECK: $x0 = COPY [[A1_P1]](s64)
; CHECK: $x1 = COPY [[A1_P2]](s64)
; CHECK: $x2 = COPY [[A2_P1]](s64)
; CHECK: $x3 = COPY [[A2_P2]](s64)
; CHECK: $x4 = COPY [[PTR]](p0)
; CHECK: BL @callee_s128, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $x1, implicit $x2, implicit $x3, implicit $x4
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
define void @caller_s128(i128 *%ptr) {
%v = load i128, i128 *%ptr
call void @callee_s128(i128 %v, i128 %v, i128 *%ptr)
ret void
}
22 changes: 2 additions & 20 deletions llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ target triple = "aarch64--"

; We use __fixunstfti as the common denominator for __fixunstfti on Linux and
; ___fixunstfti on iOS
; ERROR: unable to lower arguments: i128 (i128)* (in function: ABIi128)
; ERROR: unable to translate instruction: ret
; FALLBACK: ldr q0,
; FALLBACK-NEXT: bl __fixunstfti
;
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to lower arguments: i128 (i128)* (in function: ABIi128)
; FALLBACK-WITH-REPORT-ERR: unable to translate instruction: ret
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for ABIi128
; FALLBACK-WITH-REPORT-OUT-LABEL: ABIi128:
; FALLBACK-WITH-REPORT-OUT: ldr q0,
Expand Down Expand Up @@ -96,24 +96,6 @@ define void @test_write_register_intrin() {
@_ZTIi = external global i8*
declare i32 @__gxx_personality_v0(...)

; Check that we fallback on invoke translation failures.
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to translate instruction: invoke: ' invoke void %callee(i128 0)
; FALLBACK-WITH-REPORT-NEXT: to label %continue unwind label %broken' (in function: invoke_weird_type)
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for invoke_weird_type
; FALLBACK-WITH-REPORT-OUT-LABEL: invoke_weird_type:
define void @invoke_weird_type(void(i128)* %callee) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
invoke void %callee(i128 0)
to label %continue unwind label %broken

broken:
landingpad { i8*, i32 } catch i8* bitcast(i8** @_ZTIi to i8*)
ret void

continue:
ret void
}

; Check that we fallback on invoke translation failures.
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to legalize instruction: %0:_(s128) = G_FCONSTANT fp128 0xL00000000000000004000000000000000
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for test_quad_dump
; FALLBACK-WITH-REPORT-OUT-LABEL: test_quad_dump:
Expand Down