summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMCallLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMCallLowering.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMCallLowering.cpp23
1 files changed, 18 insertions, 5 deletions
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp
index 6dc0e862555..bfa0d9f7c30 100644
--- a/llvm/lib/Target/ARM/ARMCallLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp
@@ -343,13 +343,26 @@ struct IncomingValueHandler : public CallLowering::ValueHandler {
assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
- assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
- assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
+ auto ValSize = VA.getValVT().getSizeInBits();
+ auto LocSize = VA.getLocVT().getSizeInBits();
+
+ assert(ValSize <= 64 && "Unsupported value size");
+ assert(LocSize <= 64 && "Unsupported location size");
- // The necessary extensions are handled on the other side of the ABI
- // boundary.
markPhysRegUsed(PhysReg);
- MIRBuilder.buildCopy(ValVReg, PhysReg);
+ if (ValSize == LocSize) {
+ MIRBuilder.buildCopy(ValVReg, PhysReg);
+ } else {
+ assert(ValSize < LocSize && "Extensions not supported");
+
+ // We cannot create a truncating copy, nor a trunc of a physical register.
+ // Therefore, we need to copy the content of the physical register into a
+ // virtual one and then truncate that.
+ auto PhysRegToVReg =
+ MRI.createGenericVirtualRegister(LLT::scalar(LocSize));
+ MIRBuilder.buildCopy(PhysRegToVReg, PhysReg);
+ MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
+ }
}
unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
OpenPOWER on IntegriCloud