Index: lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- lib/Target/ARM/ARMBaseInstrInfo.cpp +++ lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -963,6 +963,17 @@ MFI.getObjectSize(FI), Align); switch (TRI->getSpillSize(*RC)) { + case 2: + if (ARM::HPRRegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(ARM::VSTRH)) + .addReg(SrcReg, getKillRegState(isKill)) + .addFrameIndex(FI) + .addImm(0) + .addMemOperand(MMO) + .add(predOps(ARMCC::AL)); + } else + llvm_unreachable("Unknown reg class!"); + break; case 4: if (ARM::GPRRegClass.hasSubClassEq(RC)) { BuildMI(MBB, I, DL, get(ARM::STRi12)) @@ -1161,6 +1172,16 @@ MFI.getObjectSize(FI), Align); switch (TRI->getSpillSize(*RC)) { + case 2: + if (ARM::HPRRegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(ARM::VLDRH), DestReg) + .addFrameIndex(FI) + .addImm(0) + .addMemOperand(MMO) + .add(predOps(ARMCC::AL)); + } else + llvm_unreachable("Unknown reg class!"); + break; case 4: if (ARM::GPRRegClass.hasSubClassEq(RC)) { BuildMI(MBB, I, DL, get(ARM::LDRi12), DestReg) @@ -1168,7 +1189,6 @@ .addImm(0) .addMemOperand(MMO) .add(predOps(ARMCC::AL)); - } else if (ARM::SPRRegClass.hasSubClassEq(RC)) { BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg) .addFrameIndex(FI) Index: test/CodeGen/ARM/fp16-instructions.ll =================================================================== --- test/CodeGen/ARM/fp16-instructions.ll +++ test/CodeGen/ARM/fp16-instructions.ll @@ -7,6 +7,8 @@ ; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FP16 ; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FULLFP16 +; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+fullfp16 -O0 | FileCheck %s --check-prefixes=CHECK-SPILL-RELOAD + ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+vfp3 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-VFP3 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FP16 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FULLFP16 @@ -714,3 +716,36 @@ ; CHECK-LABEL: ThumbAddrMode5FP16 ; CHECK-SOFTFP-FULLFP16: vstr.16 s0, [sp, #2] } + +; Test function calls to check store/load reg to/from stack +define i32 @fn1() { +entry: + %retval = alloca i32, align 4 + %coerce = alloca half, align 2 + %tmp = alloca i32, align 4 + %coerce1 = alloca half, align 2 + %tmp2 = alloca i32, align 4 + store half 0xH7C00, half* %coerce, align 2 + %0 = bitcast i32* %tmp to i8* + %1 = bitcast half* %coerce to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 2 %1, i32 2, i1 false) + %2 = load i32, i32* %tmp, align 4 + %call = call i32 bitcast (i32 (...)* @fn2 to i32 (i32)*)(i32 %2) + store half 0xH7C00, half* %coerce1, align 2 + %3 = bitcast i32* %tmp2 to i8* + %4 = bitcast half* %coerce1 to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 2 %4, i32 2, i1 false) + %5 = load i32, i32* %tmp2, align 4 + %call3 = call i32 bitcast (i32 (...)* @fn3 to i32 (i32)*)(i32 %5) + %6 = load i32, i32* %retval, align 4 + ret i32 %6 + +; CHECK-SPILL-RELOAD-LABEL: fn1: +; CHECK-SPILL-RELOAD: vstr.16 s0, [sp, #{{.}}] @ 2-byte Spill +; CHECK-SPILL-RELOAD-NEXT: bl fn2 +; CHECK-SPILL-RELOAD-NEXT: vldr.16 s0, [sp, #8] @ 2-byte Reload +} + +declare dso_local i32 @fn2(...) #1 +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i1) #2 +declare dso_local i32 @fn3(...) #1