Index: llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp +++ llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp @@ -638,7 +638,7 @@ // 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 @@ // 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 { Index: llvm/trunk/test/CodeGen/ARM/fp16-frame-lowering.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/fp16-frame-lowering.ll +++ llvm/trunk/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*)