Index: lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- lib/Target/ARM/ARMAsmPrinter.cpp +++ lib/Target/ARM/ARMAsmPrinter.cpp @@ -1111,6 +1111,12 @@ // temporary to workaround PR11902. if (MO.isImplicit()) continue; + // Registers, pushed as a part of folding an SP update into the push + // instruction are marked as undef and should not be restored when + // unwinding, because the function can modify the corresponding stack + // slots. + if (MO.isUndef()) + continue; RegList.push_back(MO.getReg()); } break; Index: lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- lib/Target/ARM/ARMBaseInstrInfo.cpp +++ lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2277,9 +2277,9 @@ --CurRegEnc) { unsigned CurReg = RegClass->getRegister(CurRegEnc); if (!IsPop) { - // Pushing any register is completely harmless, mark the - // register involved as undef since we don't care about it in - // the slightest. + // Pushing any register is completely harmless, mark the register involved + // as undef since we don't care about its value and must not restore it + // during stack unwinding. RegList.push_back(MachineOperand::CreateReg(CurReg, false, false, false, false, true)); --RegsNeeded; Index: test/CodeGen/ARM/PR35379.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/PR35379.ll @@ -0,0 +1,24 @@ +; RUN: llc -mtriple=armv7a-eabi < %s | FileCheck %s --check-prefix=CHECK-ARM +; RUN: llc -mtriple=armv6m-eabi < %s | FileCheck %s --check-prefix=CHECK-THM + +; Function Attrs: minsize optsize +define void @work() local_unnamed_addr #0 { +entry: + %i = alloca i32, align 4 + %0 = bitcast i32* %i to i8* + store i32 1, i32* %i, align 4 + call void @impl(i32* nonnull %i) + ret void +} +; CHECK-ARM: .save {r11, lr} +; CHECK-ARM-NEXT: push {r9, r10, r11, lr} +; CHECK-ARM: pop {r2, r3, r11, pc} + +; CHECK-THM: .save {r7, lr} +; CHECK-THM-NEXT: push {r5, r6, r7, lr} +; CHECK-THM: pop {r2, r3, r7, pc} + +; Function Attrs: minsize optsize +declare void @impl(i32*) local_unnamed_addr #0 + +attributes #0 = { minsize optsize }