Index: llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.h =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.h +++ llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.h @@ -40,8 +40,8 @@ int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const override; int resolveFrameIndexReference(const MachineFunction &MF, int FI, - unsigned &FrameReg, - bool PreferFP = false) const; + unsigned &FrameReg, bool PreferFP, + bool ForSimm) const; bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector &CSI, Index: llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1497,7 +1497,11 @@ int AArch64FrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const { - return resolveFrameIndexReference(MF, FI, FrameReg); + return resolveFrameIndexReference( + MF, FI, FrameReg, + /*PreferFP=*/ + MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress), + /*ForSimm=*/false); } int AArch64FrameLowering::getNonLocalFrameIndexReference( @@ -1530,7 +1534,8 @@ int AArch64FrameLowering::resolveFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg, - bool PreferFP) const { + bool PreferFP, + bool ForSimm) const { const auto &MFI = MF.getFrameInfo(); const auto *RegInfo = static_cast( MF.getSubtarget().getRegisterInfo()); @@ -1561,11 +1566,11 @@ assert(hasFP(MF) && "Re-aligned stack must have frame pointer"); UseFP = true; } else if (hasFP(MF) && !RegInfo->needsStackRealignment(MF)) { - // If the FPOffset is negative, we have to keep in mind that the - // available offset range for negative offsets is smaller than for - // positive ones. If an offset is - // available via the FP and the SP, use whichever is closest. - bool FPOffsetFits = FPOffset >= -256; + // If the FPOffset is negative and we're producing a signed immediate, we + // have to keep in mind that the available offset range for negative + // offsets is smaller than for positive ones. If an offset is available + // via the FP and the SP, use whichever is closest. + bool FPOffsetFits = !ForSimm || FPOffset >= -256; PreferFP |= Offset > -FPOffset; if (MFI.hasVarSizedObjects()) { Index: llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -453,7 +453,8 @@ if (MI.isDebugValue() || MI.getOpcode() == TargetOpcode::STACKMAP || MI.getOpcode() == TargetOpcode::PATCHPOINT) { Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg, - /*PreferFP=*/true); + /*PreferFP=*/true, + /*ForSimm=*/false); Offset += MI.getOperand(FIOperandNum + 1).getImm(); MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/); MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); @@ -468,7 +469,8 @@ } // Modify MI as necessary to handle as much of 'Offset' as possible - Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg); + Offset = TFI->resolveFrameIndexReference( + MF, FrameIndex, FrameReg, /*PreferFP=*/false, /*ForSimm=*/true); if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII)) return; Index: llvm/trunk/test/CodeGen/AArch64/hwasan-prefer-fp.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/hwasan-prefer-fp.ll +++ llvm/trunk/test/CodeGen/AArch64/hwasan-prefer-fp.ll @@ -0,0 +1,41 @@ +; RUN: llc -o - %s -filetype=obj -frame-pointer=all | llvm-dwarfdump - | FileCheck %s + +target triple="aarch64--" + +define void @f() sanitize_hwaddress !dbg !6 { +entry: + %x = call i8* @g(i32 0) + %a = alloca [128 x i8] + %b = alloca [128 x i8] + ; CHECK: DW_AT_location (DW_OP_fbreg + call void @llvm.dbg.declare(metadata [128 x i8]* %a, metadata !12, metadata !DIExpression()), !dbg !14 + ; CHECK: DW_AT_location (DW_OP_fbreg + call void @llvm.dbg.declare(metadata [128 x i8]* %b, metadata !13, metadata !DIExpression()), !dbg !14 + ret void, !dbg !15 +} + +declare i8* @g(i32) + +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "x.c", directory: "/") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang"} +!6 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, flags: +DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2) +!7 = !DISubroutineType(types: !8) +!8 = !{null, !9} +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !11) +!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!12 = !DILocalVariable(name: "a", scope: !6, file: !1, line: 1, type: !9) +!13 = !DILocalVariable(name: "b", scope: !6, file: !1, line: 1, type: !9) +!14 = !DILocation(line: 1, column: 29, scope: !6) +!15 = !DILocation(line: 1, column: 37, scope: !6)