diff --git a/lib/Target/ARM/Thumb2InstrInfo.cpp b/lib/Target/ARM/Thumb2InstrInfo.cpp index 1ed35fb3d38..6ddd71cf8d3 100644 --- a/lib/Target/ARM/Thumb2InstrInfo.cpp +++ b/lib/Target/ARM/Thumb2InstrInfo.cpp @@ -638,7 +638,7 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, // Replace the FrameIndex with fp/sp MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); if (isSub) { - if (AddrMode == ARMII::AddrMode5) + if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16) // FIXME: Not consistent. ImmedOffset |= 1 << NumBits; else @@ -652,7 +652,7 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, // Otherwise, offset doesn't fit. Pull in what we can to simplify ImmedOffset = ImmedOffset & Mask; if (isSub) { - if (AddrMode == ARMII::AddrMode5) + if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16) // FIXME: Not consistent. ImmedOffset |= 1 << NumBits; else { diff --git a/test/CodeGen/ARM/fp16-frame-lowering.ll b/test/CodeGen/ARM/fp16-frame-lowering.ll new file mode 100644 index 00000000000..a9ffc3928e9 --- /dev/null +++ b/test/CodeGen/ARM/fp16-frame-lowering.ll @@ -0,0 +1,22 @@ +; RUN: llc < %s -mtriple armv8a--none-eabi -mattr=+fullfp16 | FileCheck %s +; RUN: llc < %s -mtriple armv8a--none-eabi -mattr=+fullfp16,+thumb-mode | FileCheck %s + +; Check that frame lowering for the fp16 instructions works correctly with +; negative offsets (which happens when using the frame pointer). + +define void @foo(i32 %count) { +entry: + %half_alloca = alloca half, align 2 +; CHECK: vstr.16 {{s[0-9]+}}, [{{r[0-9]+}}, #-10] + store half 0.0, half* %half_alloca + call void @bar(half* %half_alloca) + + ; A variable-sized alloca to force the above store to use the frame pointer + ; instead of the stack pointer, and so need a negative offset. + %var_alloca = alloca i32, i32 %count + call void @baz(i32* %var_alloca) + ret void +} + +declare void @bar(half*) +declare void @baz(i32*)