[clang] [llvm] [SystemZ] Add support for __builtin_setjmp and __builtin_longjmp (PR #116642)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 22 10:54:54 PST 2024
https://github.com/anoopkg6 updated https://github.com/llvm/llvm-project/pull/116642
>From 79880371396d6e486bf6bacd6c4087ebdac591f8 Mon Sep 17 00:00:00 2001
From: anoop-kumar6 <anoop.kumar6 at ibm.com>
Date: Wed, 9 Oct 2024 17:17:17 +0200
Subject: [PATCH 1/9] Support for __builtin_setjmp and __builtin_longjmp
---
clang/lib/Basic/Targets/SystemZ.h | 2 +
clang/lib/CodeGen/CGBuiltin.cpp | 4 +-
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 4 +
.../Target/SystemZ/SystemZISelLowering.cpp | 273 +++++++++++++++++-
llvm/lib/Target/SystemZ/SystemZISelLowering.h | 16 +
llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 14 +
llvm/lib/Target/SystemZ/SystemZLongBranch.cpp | 3 +-
llvm/lib/Target/SystemZ/SystemZOperators.td | 12 +
.../Target/SystemZ/SystemZRegisterInfo.cpp | 5 +
llvm/lib/Target/SystemZ/SystemZRegisterInfo.h | 1 +
.../CodeGen/SystemZ/builtin-longjmp-01.ll | 34 +++
.../SystemZ/builtin-longjmp-backchain-01.ll | 36 +++
.../test/CodeGen/SystemZ/builtin-setjmp-01.ll | 69 +++++
.../SystemZ/builtin-setjmp-backchain-01.ll | 73 +++++
.../SystemZ/builtin-setjmp-longjmp-01.ll | 71 +++++
.../SystemZ/builtin-setjmp-longjmp-02.ll | 68 +++++
.../builtin-setjmp-longjmp-backchain-01.ll | 71 +++++
.../builtin-setjmp-longjmp-backchain-02.ll | 94 ++++++
.../builtin-setjmp-spills-double-01.ll | 222 ++++++++++++++
.../SystemZ/builtin-setjmp-spills-int-01.ll | 222 ++++++++++++++
20 files changed, 1291 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-backchain-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll
diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h
index f05ea473017bec..8fd336876cf174 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -247,6 +247,8 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
return RegNo < 4 ? 6 + RegNo : -1;
}
+ bool hasSjLjLowering() const override { return true; }
+
std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(256, 256);
}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 659b76dd7994b3..31edd05a18e294 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4552,7 +4552,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *StackAddr = Builder.CreateStackSave();
assert(Buf.emitRawPointer(*this)->getType() == StackAddr->getType());
- Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 2);
+ //StackSaveSlot no is hard coded here. For compatility with gcc,
+ // we are changing slot 3 to slot 4(offset 3) for __builtin_setjmp
+ Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 3);
Builder.CreateStore(StackAddr, StackSaveSlot);
// Call LLVM's EH setjmp, which is lightweight.
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index ed400e9eceb9ca..0f7e8560d5ecf3 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -686,6 +686,10 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot));
return;
}
+ //EH_SjLj_Setup is a dummy terminator instruction of size 0,
+ //used to handle the clobber register for builtin sejmp
+ case SystemZ::EH_SjLj_Setup:
+ return;
default:
Lower.lower(MI, LoweredMI);
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 3dabc5ef540cfb..43b0aecd8b499d 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -747,10 +747,20 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
ISD::INTRINSIC_VOID,
ISD::INTRINSIC_W_CHAIN});
- // Handle intrinsics.
+ // First try assuming that any undefined bits above the highest set bit
+ // and below the lowest set bit are 1s. This increases the likelihood of
+ // being able to use a sign-extended element value in VECTOR REPLICATE
+ // IMMEDIATE or a wraparound mask in VECTOR GENERATE MASK.
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
+ //we're not using SJLJ for exception handling, but they're implemented
+ //solely to support use of __builtin_setjmp / __builtin_longjmp
+ setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
+ setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
+
+
+
// We want to use MVC in preference to even a single load/store pair.
MaxStoresPerMemcpy = Subtarget.hasVector() ? 2 : 0;
MaxStoresPerMemcpyOptSize = 0;
@@ -937,6 +947,240 @@ bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
return SystemZVectorConstantInfo(Imm).isVectorConstantLegal(Subtarget);
}
+MachineBasicBlock *
+SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
+ MachineBasicBlock *MBB) const {
+
+ DebugLoc DL = MI.getDebugLoc();
+ const TargetInstrInfo *TII = Subtarget.getInstrInfo();
+ const SystemZRegisterInfo *TRI = Subtarget.getRegisterInfo();
+
+ MachineFunction *MF = MBB->getParent();
+ MachineRegisterInfo &MRI = MF->getRegInfo();
+
+ const BasicBlock *BB = MBB->getBasicBlock();
+ MachineFunction::iterator I = ++MBB->getIterator();
+
+ Register DstReg = MI.getOperand(0).getReg();
+ const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
+ assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!");
+ Register mainDstReg = MRI.createVirtualRegister(RC);
+ Register restoreDstReg = MRI.createVirtualRegister(RC);
+
+ MVT PVT = getPointerTy(MF->getDataLayout());
+ assert((PVT == MVT::i64 || PVT == MVT::i32) &&
+ "Invalid Pointer Size!");
+ // For v = setjmp(buf), we generate
+ // Algorithm:
+ //
+ // ---------
+ // | thisMBB |
+ // ---------
+ // |
+ // ------------------------
+ // | |
+ // ---------- ---------------
+ // | mainMBB | | restoreMBB |
+ // | v = 0 | | v = 1 |
+ // ---------- ---------------
+ // | |
+ // -------------------------
+ // |
+ // -----------------------------
+ // | sinkMBB |
+ // | phi(v_mainMBB,v_restoreMBB) |
+ // -----------------------------
+ // thisMBB:
+ // buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB
+ // SjLjSetup restoreMBB
+ //
+ // mainMBB:
+ // v_main = 0
+ //
+ // sinkMBB:
+ // v = phi(main, restore)
+ //
+ // restoreMBB:
+ // v_restore = 1
+
+ MachineBasicBlock *thisMBB = MBB;
+ MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(BB);
+ MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB);
+ MachineBasicBlock *restoreMBB = MF->CreateMachineBasicBlock(BB);
+ MF->insert(I, mainMBB);
+ MF->insert(I, sinkMBB);
+ MF->push_back(restoreMBB);
+ restoreMBB->setMachineBlockAddressTaken();
+
+ MachineInstrBuilder MIB;
+
+ // Transfer the remainder of BB and its successor edges to sinkMBB.
+ sinkMBB->splice(sinkMBB->begin(), MBB,
+ std::next(MachineBasicBlock::iterator(MI)), MBB->end());
+ sinkMBB->transferSuccessorsAndUpdatePHIs(MBB);
+
+ // Note that the structure of the jmp_buf used here is not compatible
+ // with that used by libc, and is not designed to be. Specifically, it
+ // stores only those 'reserved' registers that LLVM does not otherwise
+ // understand how to spill. Also, by convention, by the time this
+ // intrinsic is called, Clang has already stored the frame address in the
+ // first slot of the buffer and stack address in the third(gcc stores SP in
+ // fourth slot).
+ // clang convention:
+ // -----------------
+ // slot 1(Offset 0): Frame Pointer
+ // slot 3(Offset 2): Stack Pointer
+ // GCC following convetion :
+ // ------------------------
+ // Slot 1(Offset 0): Frame pointer
+ // Slot 2(Offset 1): Receiver (jump) address
+ // Slot 3(Offset 2): Backchain value (if building with -mbackchain)
+ // Slot 4(Offset 3): Stack pointer
+ // Slot 5(Offset 4): R13 (used to be literal pool pointer)
+ // We have made changes to clang/lib/CodeGen/CGBuiltin.cpp to change
+ // stack slot to 4(offset = 3) instead of 3 to keep it in sync with gcc
+ // Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 3);
+
+ // thisMBB:
+ const int64_t LabelOffset = 1 * PVT.getStoreSize(); //Slot 2
+ const int64_t LPOffset = 4 * PVT.getStoreSize(); //Slot 5
+
+ //Buf address
+ Register BufReg = MI.getOperand(1).getReg();
+
+ unsigned LabelReg = 0;
+ const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
+ LabelReg = MRI.createVirtualRegister(PtrRC);
+
+ //prepare IP for longjmp
+ BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LARL), LabelReg)
+ .addMBB(restoreMBB);
+
+ //store IP for return from jmp, slot 2, offset = 1
+ BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
+ .addReg(LabelReg, getKillRegState(true))
+ .addReg(BufReg)
+ .addImm(LabelOffset)
+ .addReg(0);
+
+
+ //Slot 3(Offset = 2) Backchain value (if building with -mbackchain)
+ bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain();
+ if (BackChain) {
+ const int64_t BCOffset = 2 * PVT.getStoreSize();
+ Register BCReg = MRI.createVirtualRegister(RC);
+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LG), BCReg)
+ .addReg(SystemZ::R15D)
+ .addImm(0)
+ .addReg(0);
+
+ BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
+ .addReg(BCReg)
+ .addReg(BufReg)
+ .addImm(BCOffset)
+ .addReg(0);
+ }
+
+ //LP Literal Pool in fifth slot, offset 4
+ BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
+ .addReg(SystemZ::R13D)
+ .addReg(BufReg)
+ .addImm(LPOffset)
+ .addReg(0);
+
+ //Setup
+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::EH_SjLj_Setup))
+ .addMBB(restoreMBB);
+
+ const SystemZRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
+ MIB.addRegMask(RegInfo->getNoPreservedMask());
+
+ thisMBB->addSuccessor(mainMBB);
+ thisMBB->addSuccessor(restoreMBB);
+
+ // mainMBB:
+ // mainDstReg = 0
+ BuildMI(mainMBB, DL, TII->get(SystemZ::LGHI), mainDstReg).addImm(0);
+ mainMBB->addSuccessor(sinkMBB);
+
+ // sinkMBB:
+ BuildMI(*sinkMBB, sinkMBB->begin(), DL, TII->get(SystemZ::PHI), DstReg)
+ .addReg(mainDstReg)
+ .addMBB(mainMBB)
+ .addReg(restoreDstReg)
+ .addMBB(restoreMBB);
+
+ //restoreMBB
+ BuildMI(restoreMBB, DL, TII->get(SystemZ::LGHI), restoreDstReg).addImm(1);
+ BuildMI(restoreMBB, DL, TII->get(SystemZ::J)).addMBB(sinkMBB);
+ restoreMBB->addSuccessor(sinkMBB);
+
+ MI.eraseFromParent();
+
+ return sinkMBB;
+}
+
+MachineBasicBlock *
+SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
+ MachineBasicBlock *MBB) const {
+
+ DebugLoc DL = MI.getDebugLoc();
+ const TargetInstrInfo *TII = Subtarget.getInstrInfo();
+
+ MachineFunction *MF = MBB->getParent();
+ MachineRegisterInfo &MRI = MF->getRegInfo();
+
+ MVT PVT = getPointerTy(MF->getDataLayout());
+ assert((PVT == MVT::i64 || PVT == MVT::i32) &&
+ "Invalid Pointer Size!");
+ Register BufReg = MI.getOperand(0).getReg();
+ const TargetRegisterClass *RC = MRI.getRegClass(BufReg);
+
+ Register Tmp = MRI.createVirtualRegister(RC);
+
+ MachineInstrBuilder MIB;
+
+ const int64_t LabelOffset = 1 * PVT.getStoreSize();
+ const int64_t SPOffset = 3 * PVT.getStoreSize();
+ const int64_t LPOffset = 4 * PVT.getStoreSize();
+
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), Tmp)
+ .addReg(BufReg)
+ .addImm(LabelOffset)
+ .addReg(0);
+
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R13D)
+ .addReg(BufReg)
+ .addImm(LPOffset)
+ .addReg(0);
+
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R15D)
+ .addReg(BufReg)
+ .addImm(SPOffset)
+ .addReg(0);
+
+ bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain();
+ if (BackChain) {
+ const int64_t BCOffset = 2 * PVT.getStoreSize();
+ Register BCReg = MRI.createVirtualRegister(RC);
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), BCReg)
+ .addReg(BufReg)
+ .addImm(BCOffset)
+ .addReg(0);
+
+ BuildMI(*MBB, MI, DL, TII->get(SystemZ::STG))
+ .addReg(BCReg)
+ .addReg(SystemZ::R15D)
+ .addImm(0)
+ .addReg(0);
+ }
+
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::BR)).addReg(Tmp);
+
+ MI.eraseFromParent();
+ return MBB;
+}
+
/// Returns true if stack probing through inline assembly is requested.
bool SystemZTargetLowering::hasInlineStackProbe(const MachineFunction &MF) const {
// If the function specifically requests inline stack probes, emit them.
@@ -6293,6 +6537,11 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
return lowerGET_ROUNDING(Op, DAG);
case ISD::READCYCLECOUNTER:
return lowerREADCYCLECOUNTER(Op, DAG);
+ case ISD::EH_SJLJ_SETJMP:
+ return lowerEH_SJLJ_SETJMP(Op, DAG);
+ case ISD::EH_SJLJ_LONGJMP:
+ return lowerEH_SJLJ_LONGJMP(Op, DAG);
+
default:
llvm_unreachable("Unexpected node to lower");
}
@@ -6534,6 +6783,8 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
OPCODE(VSTRS_CC);
OPCODE(VSTRSZ_CC);
OPCODE(TDC);
+ OPCODE(EH_SJLJ_SETJMP);
+ OPCODE(EH_SJLJ_LONGJMP);
OPCODE(ATOMIC_SWAPW);
OPCODE(ATOMIC_LOADW_ADD);
OPCODE(ATOMIC_LOADW_SUB);
@@ -9724,6 +9975,11 @@ MachineBasicBlock *SystemZTargetLowering::EmitInstrWithCustomInserter(
case SystemZ::PROBED_ALLOCA:
return emitProbedAlloca(MI, MBB);
+
+ case SystemZ::EH_SjLj_SetJmp:
+ return emitEHSjLjSetJmp(MI, MBB);
+ case SystemZ::EH_SjLj_LongJmp:
+ return emitEHSjLjLongJmp(MI, MBB);
case TargetOpcode::STACKMAP:
case TargetOpcode::PATCHPOINT:
@@ -9783,6 +10039,21 @@ SDValue SystemZTargetLowering::lowerGET_ROUNDING(SDValue Op,
return DAG.getMergeValues({RetVal, Chain}, dl);
}
+SDValue SystemZTargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ return DAG.getNode(SystemZISD::EH_SJLJ_SETJMP, DL,
+ DAG.getVTList(MVT::i32, MVT::Other),
+ Op.getOperand(0), Op.getOperand(1));
+}
+
+SDValue SystemZTargetLowering::lowerEH_SJLJ_LONGJMP(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ return DAG.getNode(SystemZISD::EH_SJLJ_LONGJMP, DL, MVT::Other,
+ Op.getOperand(0), Op.getOperand(1));
+}
+
SDValue SystemZTargetLowering::lowerVECREDUCE_ADD(SDValue Op,
SelectionDAG &DAG) const {
EVT VT = Op.getValueType();
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index 8c528897182d17..e192c7dad07318 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -304,6 +304,13 @@ enum NodeType : unsigned {
// Operand 2: the offset (0 for the first and 8 for the second element in the
// function descriptor)
ADA_ENTRY,
+ // EH_SJLJ_SETJMP - SjLj exception handling setjmp.
+ EH_SJLJ_SETJMP,
+
+ // EH_SJLJ_LONGJMP - SjLj exception handling longjmp.
+ EH_SJLJ_LONGJMP,
+
+
// Strict variants of scalar floating-point comparisons.
// Quiet and signaling versions.
@@ -476,6 +483,12 @@ class SystemZTargetLowering : public TargetLowering {
// LD, and having the full constant in memory enables reg/mem opcodes.
return VT != MVT::f64;
}
+ MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
+ MachineBasicBlock *MBB) const;
+
+ MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,
+ MachineBasicBlock *MBB) const;
+
bool hasInlineStackProbe(const MachineFunction &MF) const override;
AtomicExpansionKind shouldCastAtomicLoadInIR(LoadInst *LI) const override;
AtomicExpansionKind shouldCastAtomicStoreInIR(StoreInst *SI) const override;
@@ -724,6 +737,9 @@ class SystemZTargetLowering : public TargetLowering {
SDValue lowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
+
bool canTreatAsByteVector(EVT VT) const;
SDValue combineExtract(const SDLoc &DL, EVT ElemVT, EVT VecVT, SDValue OrigOp,
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index 95ed1a00e603f9..b7af22bf4aa8af 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -1871,6 +1871,20 @@ let mayLoad = 1, mayStore = 1, Defs = [CC] in {
}
}
+//--------------------------------------------------------------------------
+// Setjmp/Longjmp
+//--------------------------------------------------------------------------
+let isTerminator = 1, isBarrier = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1, Size = 0 in {
+ def EH_SjLj_Setup : Pseudo<(outs), (ins brtarget32:$dst), []>;
+}
+
+let hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
+ def EH_SjLj_SetJmp : Pseudo<(outs GR32:$dst), (ins ADDR64:$R2), [(set GR32:$dst, (z_eh_sjlj_setjmp ADDR64:$R2))]>;
+}
+
+let hasSideEffects = 1, isTerminator = 1, isBarrier = 1, usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
+ def EH_SjLj_LongJmp : Pseudo<(outs), (ins ADDR64:$R2), [(z_eh_sjlj_longjmp ADDR64:$R2)]>;
+}
//===----------------------------------------------------------------------===//
// Message-security assist
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp
index 632218cc61eefe..cd60f23a9cbb3d 100644
--- a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp
@@ -220,7 +220,8 @@ static unsigned getInstSizeInBytes(const MachineInstr &MI,
MI.isImplicitDef() || MI.getOpcode() == TargetOpcode::MEMBARRIER ||
// These have a size that may be zero:
MI.isInlineAsm() || MI.getOpcode() == SystemZ::STACKMAP ||
- MI.getOpcode() == SystemZ::PATCHPOINT) &&
+ MI.getOpcode() == SystemZ::PATCHPOINT ||
+ MI.getOpcode() == SystemZ::EH_SjLj_Setup) &&
"Missing size value for instruction.");
return Size;
}
diff --git a/llvm/lib/Target/SystemZ/SystemZOperators.td b/llvm/lib/Target/SystemZ/SystemZOperators.td
index 6cb89ccff85e68..89c99d31e3c92e 100644
--- a/llvm/lib/Target/SystemZ/SystemZOperators.td
+++ b/llvm/lib/Target/SystemZ/SystemZOperators.td
@@ -238,6 +238,12 @@ def SDT_ZTest : SDTypeProfile<1, 2,
[SDTCisVT<0, i32>,
SDTCisVT<2, i64>]>;
+def SDT_ZSetJmp : SDTypeProfile<1, 1,
+ [SDTCisInt<0>,
+ SDTCisPtrTy<1>]>;
+def SDT_ZLongJmp : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
+
+
//===----------------------------------------------------------------------===//
// Node definitions
//===----------------------------------------------------------------------===//
@@ -314,6 +320,12 @@ def z_stckf : SDNode<"SystemZISD::STCKF", SDT_ZStoreInherent,
def z_tdc : SDNode<"SystemZISD::TDC", SDT_ZTest>;
+def z_eh_sjlj_setjmp : SDNode<"SystemZISD::EH_SJLJ_SETJMP", SDT_ZSetJmp,
+ [SDNPHasChain, SDNPSideEffect]>;
+def z_eh_sjlj_longjmp : SDNode<"SystemZISD::EH_SJLJ_LONGJMP", SDT_ZLongJmp,
+ [SDNPHasChain, SDNPSideEffect]>;
+
+
// Defined because the index is an i32 rather than a pointer.
def z_vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
SDT_ZInsertVectorElt>;
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
index d246d3f3c5bd11..6d3e542c1b4e81 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
@@ -254,6 +254,11 @@ SystemZRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
return Regs->getCallPreservedMask(MF, CC);
}
+const uint32_t*
+SystemZRegisterInfo::getNoPreservedMask() const {
+ return CSR_SystemZ_NoRegs_RegMask;
+}
+
BitVector
SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
index cbc02c73f1ac70..4f497f8d23d29a 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
@@ -161,6 +161,7 @@ struct SystemZRegisterInfo : public SystemZGenRegisterInfo {
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID CC) const override;
+ const uint32_t *getNoPreservedMask() const override;
BitVector getReservedRegs(const MachineFunction &MF) const override;
bool eliminateFrameIndex(MachineBasicBlock::iterator MI,
int SPAdj, unsigned FIOperandNum,
diff --git a/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll b/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll
new file mode 100644
index 00000000000000..7e6667cb87ccd0
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll
@@ -0,0 +1,34 @@
+; RUN: llc < %s -verify-machineinstrs | FileCheck %s
+; ModuleID = 'longjmp.c'
+source_filename = "longjmp.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+
+; Function Attrs: noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+; CHECK: stmg %r13, %r15, 104(%r15)
+; CHECK: larl %r1, buf
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: br %r2
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+attributes #0 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
new file mode 100644
index 00000000000000..137dd754892b28
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
@@ -0,0 +1,36 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = 'longjmp.c'
+source_filename = "longjmp.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+
+; Function Attrs: noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+; CHECK: stmg %r13, %r15, 104(%r15)
+; CHECK: larl %r1, buf
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: lg %r1, 16(%r1)
+; CHECK: stg %r1, 0(%r15)
+; CHECK: br %r2
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+attributes #0 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-01.ll
new file mode 100644
index 00000000000000..3f22e6d3699575
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-01.ll
@@ -0,0 +1,69 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = 'setjmp.c'
+source_filename = "setjmp.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+
+; Function Attrs: nounwind
+define dso_local signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #0 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -224
+; CHECK: std %f8, 216(%r15)
+; CHECK: std %f9, 208(%r15)
+; CHECK: std %f10, 200(%r15)
+; CHECK: std %f11, 192(%r15)
+; CHECK: std %f12, 184(%r15)
+; CHECK: std %f13, 176(%r15)
+; CHECK: std %f14, 168(%r15)
+; CHECK: std %f15, 160(%r15)
+; CHECK: la %r0, 224(%r15)
+; CHECK: stgrl %r0, buf
+; CHECK: stgrl %r15, buf+24
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_2
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r13, 32(%r1)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %tobool.not = icmp eq i32 %2, 0
+ br i1 %tobool.not, label %if.end, label %return
+
+if.end: ; preds = %entry
+ tail call void @foo() #3
+ br label %return
+
+return: ; preds = %entry, %if.end
+ %retval.0 = phi i32 [ 1, %if.end ], [ 0, %entry ]
+ ret i32 %retval.0
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #1
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #2
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+declare void @foo() local_unnamed_addr #4
+
+attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #3 = { nounwind }
+attributes #4 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-backchain-01.ll
new file mode 100644
index 00000000000000..da281cd6aef710
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-backchain-01.ll
@@ -0,0 +1,73 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = 'setjmp.c'
+source_filename = "setjmp.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+
+; Function Attrs: nounwind
+define dso_local signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #0 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: lgr %r1, %r15
+; CHECK: aghi %r15, -224
+; CHECK: stg %r1, 0(%r15)
+; CHECK: std %f8, 216(%r15)
+; CHECK: std %f9, 208(%r15)
+; CHECK: std %f10, 200(%r15)
+; CHECK: std %f11, 192(%r15)
+; CHECK: std %f12, 184(%r15)
+; CHECK: std %f13, 176(%r15)
+; CHECK: std %f14, 168(%r15)
+; CHECK: std %f15, 160(%r15)
+; CHECK: la %r0, 224(%r15)
+; CHECK: stgrl %r0, buf
+; CHECK: stgrl %r15, buf+24
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_2
+; CHECK: stg %r0, 8(%r1)
+; CHECK: lg %r0, 0(%r15)
+; CHECK: stg %r0, 16(%r1)
+; CHECK: stg %r13, 32(%r1)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %tobool.not = icmp eq i32 %2, 0
+ br i1 %tobool.not, label %if.end, label %return
+
+if.end: ; preds = %entry
+ tail call void @foo() #3
+ br label %return
+
+return: ; preds = %entry, %if.end
+ %retval.0 = phi i32 [ 1, %if.end ], [ 0, %entry ]
+ ret i32 %retval.0
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #1
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #2
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+declare void @foo() local_unnamed_addr #4
+
+attributes #0 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #3 = { nounwind }
+attributes #4 = { "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-01.ll
new file mode 100644
index 00000000000000..98a5c4c1e77fbe
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-01.ll
@@ -0,0 +1,71 @@
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+; CHECK: call foo
+; CHECK: return
+; ModuleID = 'builtin-setjmp-longjmp-01.c'
+source_filename = "builtin-setjmp-longjmp-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at str = private unnamed_addr constant [9 x i8] c"call foo\00", align 1
+ at str.2 = private unnamed_addr constant [7 x i8] c"return\00", align 1
+
+; Function Attrs: noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+; Function Attrs: nounwind
+define dso_local noundef signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #2 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %tobool.not = icmp eq i32 %2, 0
+ br i1 %tobool.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %puts2 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.2)
+ ret i32 0
+
+if.end: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #3
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #4
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+attributes #2 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #5 = { nounwind }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll
new file mode 100644
index 00000000000000..c8d52e876aef54
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll
@@ -0,0 +1,68 @@
+;
+; RUN: llc < %s | FileCheck %s
+
+; ModuleID = 't.c'
+source_filename = "t.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+
+; Function Attrs: noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+; CHECK: stmg %r13, %r15, 104(%r15)
+; CHECK: larl %r1, buf
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: br %r2
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+; Function Attrs: nounwind
+define dso_local noundef signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #2 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %tobool.not = icmp eq i32 %2, 0
+ br i1 %tobool.not, label %if.end, label %return
+
+if.end: ; preds = %entry
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+
+return: ; preds = %entry
+ ret i32 0
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #3
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #4
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+attributes #0 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+attributes #2 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #5 = { nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-01.ll
new file mode 100644
index 00000000000000..1a118c381a3b61
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-01.ll
@@ -0,0 +1,71 @@
+; RUN: clang -mbackchain -o %t %s
+; RUN: %t | FileCheck %s
+; CHECK: call foo
+; CHECK: return
+; ModuleID = 'builtin-setjmp-longjmp-backchain-02.c'
+source_filename = "builtin-setjmp-longjmp-backchain-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at str = private unnamed_addr constant [9 x i8] c"call foo\00", align 1
+ at str.2 = private unnamed_addr constant [7 x i8] c"return\00", align 1
+
+; Function Attrs: noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+; Function Attrs: nounwind
+define dso_local noundef signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #2 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %tobool.not = icmp eq i32 %2, 0
+ br i1 %tobool.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %puts2 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.2)
+ ret i32 0
+
+if.end: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #3
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #4
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+attributes #2 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #5 = { nounwind }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-02.ll
new file mode 100644
index 00000000000000..627c29469ca3c9
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-02.ll
@@ -0,0 +1,94 @@
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+; CHECK: setjmp has been called
+; CHECK-NEXT: Calling function foo
+; CHECK-NEXT: Calling longjmp from inside function foo
+; CHECK-NEXT: longjmp has been called
+; CHECK-NEXT: Performing function recover
+; ModuleID = 'builtin-setjmp-longjmp-02.c'
+source_filename = "builtin-setjmp-longjmp-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+ at str.7 = private unnamed_addr constant [23 x i8] c"setjmp has been called\00", align 1
+ at str.8 = private unnamed_addr constant [21 x i8] c"Calling function foo\00", align 1
+ at str.10 = private unnamed_addr constant [24 x i8] c"longjmp has been called\00", align 1
+
+; Function Attrs: noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+; Function Attrs: nofree nounwind
+define dso_local void @recover() local_unnamed_addr #2 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #0 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %2, 0
+ br i1 %cmp.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %puts6 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 1) #8
+ unreachable
+
+if.end: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.7)
+ %puts4 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.8)
+ %puts.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #3
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #4
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #6
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+attributes #0 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+attributes #2 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #5 = { nounwind }
+attributes #6 = { nofree noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+attributes #8 = { cold noreturn nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll
new file mode 100644
index 00000000000000..926048b677cdc0
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll
@@ -0,0 +1,222 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = 'builtin-setjmp-spills-double-01.c'
+source_filename = "builtin-setjmp-spills-double-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at s = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at r = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at q = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at p = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at o = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at n = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at m = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at l = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at k = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at j = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at i = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at h = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at g = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at f = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at e = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at d = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at c = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at b = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at a = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at .str.2 = private unnamed_addr constant [9 x i8] c"a = %lf\0A\00", align 2
+ at .str.3 = private unnamed_addr constant [9 x i8] c"b = %lf\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [9 x i8] c"c = %lf\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [9 x i8] c"d = %lf\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [9 x i8] c"e = %lf\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"f = %lf\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [9 x i8] c"g = %lf\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [9 x i8] c"h = %lf\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [9 x i8] c"i = %lf\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [9 x i8] c"j = %lf\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [9 x i8] c"k = %lf\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [9 x i8] c"l = %lf\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [9 x i8] c"m = %lf\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [9 x i8] c"n = %lf\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [9 x i8] c"o = %lf\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [9 x i8] c"p = %lf\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [9 x i8] c"q = %lf\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [9 x i8] c"r = %lf\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [9 x i8] c"s = %lf\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [9 x i8] c"t = %lf\0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.22 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local double @func() local_unnamed_addr #0 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -224
+; CHECK: std %f8, 216(%r15)
+; CHECK: std %f9, 208(%r15)
+; CHECK: std %f10, 200(%r15)
+; CHECK: std %f11, 192(%r15)
+; CHECK: std %f12, 184(%r15)
+; CHECK: std %f13, 176(%r15)
+; CHECK: std %f14, 168(%r15)
+; CHECK: std %f15, 160(%r15)
+; CHECK: la %r0, 224(%r15)
+; CHECK: stgrl %r0, buf
+; CHECK: stgrl %r15, buf+24
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_3
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r13, 32(%r1)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %2, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ store double 1.000000e+00, ptr @t, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @s, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @r, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @q, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @p, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @o, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @n, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @m, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @l, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @k, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @j, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @i, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @h, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @g, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @f, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @e, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @d, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @c, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @b, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @a, align 8, !tbaa !4
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
+ br label %if.end
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ %3 = load double, ptr @a, align 8, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, double noundef %3)
+ %4 = load double, ptr @b, align 8, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, double noundef %4)
+ %5 = load double, ptr @c, align 8, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, double noundef %5)
+ %6 = load double, ptr @d, align 8, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, double noundef %6)
+ %7 = load double, ptr @e, align 8, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, double noundef %7)
+ %8 = load double, ptr @f, align 8, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, double noundef %8)
+ %9 = load double, ptr @g, align 8, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, double noundef %9)
+ %10 = load double, ptr @h, align 8, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, double noundef %10)
+ %11 = load double, ptr @i, align 8, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, double noundef %11)
+ %12 = load double, ptr @j, align 8, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, double noundef %12)
+ %13 = load double, ptr @k, align 8, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, double noundef %13)
+ %14 = load double, ptr @l, align 8, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, double noundef %14)
+ %15 = load double, ptr @m, align 8, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, double noundef %15)
+ %16 = load double, ptr @n, align 8, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, double noundef %16)
+ %17 = load double, ptr @o, align 8, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, double noundef %17)
+ %18 = load double, ptr @p, align 8, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, double noundef %18)
+ %19 = load double, ptr @q, align 8, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, double noundef %19)
+ %20 = load double, ptr @r, align 8, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, double noundef %20)
+ %21 = load double, ptr @s, align 8, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, double noundef %21)
+ %22 = load double, ptr @t, align 8, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, double noundef %22)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %23 = load double, ptr @a, align 8, !tbaa !4
+ %24 = load double, ptr @b, align 8, !tbaa !4
+ %add = fadd double %23, %24
+ %25 = load double, ptr @c, align 8, !tbaa !4
+ %add22 = fadd double %add, %25
+ %26 = load double, ptr @d, align 8, !tbaa !4
+ %add23 = fadd double %add22, %26
+ %27 = load double, ptr @e, align 8, !tbaa !4
+ %add24 = fadd double %add23, %27
+ %28 = load double, ptr @f, align 8, !tbaa !4
+ %add25 = fadd double %add24, %28
+ %29 = load double, ptr @g, align 8, !tbaa !4
+ %add26 = fadd double %add25, %29
+ %30 = load double, ptr @h, align 8, !tbaa !4
+ %add27 = fadd double %add26, %30
+ %31 = load double, ptr @i, align 8, !tbaa !4
+ %add28 = fadd double %add27, %31
+ %32 = load double, ptr @j, align 8, !tbaa !4
+ %add29 = fadd double %add28, %32
+ %33 = load double, ptr @k, align 8, !tbaa !4
+ %add30 = fadd double %add29, %33
+ %34 = load double, ptr @l, align 8, !tbaa !4
+ %add31 = fadd double %add30, %34
+ %35 = load double, ptr @m, align 8, !tbaa !4
+ %add32 = fadd double %add31, %35
+ %36 = load double, ptr @n, align 8, !tbaa !4
+ %add33 = fadd double %add32, %36
+ %37 = load double, ptr @o, align 8, !tbaa !4
+ %add34 = fadd double %add33, %37
+ %38 = load double, ptr @p, align 8, !tbaa !4
+ %add35 = fadd double %add34, %38
+ %39 = load double, ptr @q, align 8, !tbaa !4
+ %add36 = fadd double %add35, %39
+ %40 = load double, ptr @r, align 8, !tbaa !4
+ %add37 = fadd double %add36, %40
+ %41 = load double, ptr @s, align 8, !tbaa !4
+ %add38 = fadd double %add37, %41
+ %42 = load double, ptr @t, align 8, !tbaa !4
+ %add39 = fadd double %add38, %42
+ ret double %add39
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #1
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #2
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #5
+
+attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #3 = { nounwind }
+attributes #4 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"double", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll
new file mode 100644
index 00000000000000..a9d026912da1af
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll
@@ -0,0 +1,222 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = 'builtin-setjmp-spills-int-01.c'
+source_filename = "builtin-setjmp-spills-int-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local local_unnamed_addr global i32 0, align 4
+ at s = dso_local local_unnamed_addr global i32 0, align 4
+ at r = dso_local local_unnamed_addr global i32 0, align 4
+ at q = dso_local local_unnamed_addr global i32 0, align 4
+ at p = dso_local local_unnamed_addr global i32 0, align 4
+ at o = dso_local local_unnamed_addr global i32 0, align 4
+ at n = dso_local local_unnamed_addr global i32 0, align 4
+ at m = dso_local local_unnamed_addr global i32 0, align 4
+ at l = dso_local local_unnamed_addr global i32 0, align 4
+ at k = dso_local local_unnamed_addr global i32 0, align 4
+ at j = dso_local local_unnamed_addr global i32 0, align 4
+ at i = dso_local local_unnamed_addr global i32 0, align 4
+ at h = dso_local local_unnamed_addr global i32 0, align 4
+ at g = dso_local local_unnamed_addr global i32 0, align 4
+ at f = dso_local local_unnamed_addr global i32 0, align 4
+ at e = dso_local local_unnamed_addr global i32 0, align 4
+ at d = dso_local local_unnamed_addr global i32 0, align 4
+ at c = dso_local local_unnamed_addr global i32 0, align 4
+ at b = dso_local local_unnamed_addr global i32 0, align 4
+ at a = dso_local local_unnamed_addr global i32 0, align 4
+ at .str.2 = private unnamed_addr constant [8 x i8] c"a = %d\0A\00", align 2
+ at .str.3 = private unnamed_addr constant [8 x i8] c"b = %d\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [8 x i8] c"c = %d\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [8 x i8] c"d = %d\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [8 x i8] c"e = %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [8 x i8] c"f = %d\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [8 x i8] c"g = %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [8 x i8] c"h = %d\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [8 x i8] c"j = %d\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [8 x i8] c"k = %d\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [8 x i8] c"l = %d\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [8 x i8] c"m = %d\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [8 x i8] c"n = %d\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [8 x i8] c"o = %d\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [8 x i8] c"p = %d\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [8 x i8] c"q = %d\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [8 x i8] c"r = %d\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [8 x i8] c"s = %d\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [8 x i8] c"t = %d\0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.22 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local signext i32 @func() local_unnamed_addr #0 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -224
+; CHECK: std %f8, 216(%r15)
+; CHECK: std %f9, 208(%r15)
+; CHECK: std %f10, 200(%r15)
+; CHECK: std %f11, 192(%r15)
+; CHECK: std %f12, 184(%r15)
+; CHECK: std %f13, 176(%r15)
+; CHECK: std %f14, 168(%r15)
+; CHECK: std %f15, 160(%r15)
+; CHECK: la %r0, 224(%r15)
+; CHECK: stgrl %r0, buf
+; CHECK: stgrl %r15, buf+24
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_3
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r13, 32(%r1)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %2, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ store i32 1, ptr @t, align 4, !tbaa !4
+ store i32 1, ptr @s, align 4, !tbaa !4
+ store i32 1, ptr @r, align 4, !tbaa !4
+ store i32 1, ptr @q, align 4, !tbaa !4
+ store i32 1, ptr @p, align 4, !tbaa !4
+ store i32 1, ptr @o, align 4, !tbaa !4
+ store i32 1, ptr @n, align 4, !tbaa !4
+ store i32 1, ptr @m, align 4, !tbaa !4
+ store i32 1, ptr @l, align 4, !tbaa !4
+ store i32 1, ptr @k, align 4, !tbaa !4
+ store i32 1, ptr @j, align 4, !tbaa !4
+ store i32 1, ptr @i, align 4, !tbaa !4
+ store i32 1, ptr @h, align 4, !tbaa !4
+ store i32 1, ptr @g, align 4, !tbaa !4
+ store i32 1, ptr @f, align 4, !tbaa !4
+ store i32 1, ptr @e, align 4, !tbaa !4
+ store i32 1, ptr @d, align 4, !tbaa !4
+ store i32 1, ptr @c, align 4, !tbaa !4
+ store i32 1, ptr @b, align 4, !tbaa !4
+ store i32 1, ptr @a, align 4, !tbaa !4
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
+ br label %if.end
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ %3 = load i32, ptr @a, align 4, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %3)
+ %4 = load i32, ptr @b, align 4, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %4)
+ %5 = load i32, ptr @c, align 4, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %5)
+ %6 = load i32, ptr @d, align 4, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, i32 noundef signext %6)
+ %7 = load i32, ptr @e, align 4, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %7)
+ %8 = load i32, ptr @f, align 4, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %8)
+ %9 = load i32, ptr @g, align 4, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %9)
+ %10 = load i32, ptr @h, align 4, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %10)
+ %11 = load i32, ptr @i, align 4, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, i32 noundef signext %11)
+ %12 = load i32, ptr @j, align 4, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %12)
+ %13 = load i32, ptr @k, align 4, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, i32 noundef signext %13)
+ %14 = load i32, ptr @l, align 4, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %14)
+ %15 = load i32, ptr @m, align 4, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, i32 noundef signext %15)
+ %16 = load i32, ptr @n, align 4, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, i32 noundef signext %16)
+ %17 = load i32, ptr @o, align 4, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, i32 noundef signext %17)
+ %18 = load i32, ptr @p, align 4, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, i32 noundef signext %18)
+ %19 = load i32, ptr @q, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, i32 noundef signext %19)
+ %20 = load i32, ptr @r, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, i32 noundef signext %20)
+ %21 = load i32, ptr @s, align 4, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, i32 noundef signext %21)
+ %22 = load i32, ptr @t, align 4, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, i32 noundef signext %22)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %23 = load i32, ptr @a, align 4, !tbaa !4
+ %24 = load i32, ptr @b, align 4, !tbaa !4
+ %add = add nsw i32 %24, %23
+ %25 = load i32, ptr @c, align 4, !tbaa !4
+ %add22 = add nsw i32 %add, %25
+ %26 = load i32, ptr @d, align 4, !tbaa !4
+ %add23 = add nsw i32 %add22, %26
+ %27 = load i32, ptr @e, align 4, !tbaa !4
+ %add24 = add nsw i32 %add23, %27
+ %28 = load i32, ptr @f, align 4, !tbaa !4
+ %add25 = add nsw i32 %add24, %28
+ %29 = load i32, ptr @g, align 4, !tbaa !4
+ %add26 = add nsw i32 %add25, %29
+ %30 = load i32, ptr @h, align 4, !tbaa !4
+ %add27 = add nsw i32 %add26, %30
+ %31 = load i32, ptr @i, align 4, !tbaa !4
+ %add28 = add nsw i32 %add27, %31
+ %32 = load i32, ptr @j, align 4, !tbaa !4
+ %add29 = add nsw i32 %add28, %32
+ %33 = load i32, ptr @k, align 4, !tbaa !4
+ %add30 = add nsw i32 %add29, %33
+ %34 = load i32, ptr @l, align 4, !tbaa !4
+ %add31 = add nsw i32 %add30, %34
+ %35 = load i32, ptr @m, align 4, !tbaa !4
+ %add32 = add nsw i32 %add31, %35
+ %36 = load i32, ptr @n, align 4, !tbaa !4
+ %add33 = add nsw i32 %add32, %36
+ %37 = load i32, ptr @o, align 4, !tbaa !4
+ %add34 = add nsw i32 %add33, %37
+ %38 = load i32, ptr @p, align 4, !tbaa !4
+ %add35 = add nsw i32 %add34, %38
+ %39 = load i32, ptr @q, align 4, !tbaa !4
+ %add36 = add nsw i32 %add35, %39
+ %40 = load i32, ptr @r, align 4, !tbaa !4
+ %add37 = add nsw i32 %add36, %40
+ %41 = load i32, ptr @s, align 4, !tbaa !4
+ %add38 = add nsw i32 %add37, %41
+ %42 = load i32, ptr @t, align 4, !tbaa !4
+ %add39 = add nsw i32 %add38, %42
+ ret i32 %add39
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #1
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #2
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #5
+
+attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #3 = { nounwind }
+attributes #4 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
>From f8040a3b8b6a43e55efd7634bcac63f2c7e62ae4 Mon Sep 17 00:00:00 2001
From: anoop-kumar6 <anoop.kumar6 at ibm.com>
Date: Fri, 25 Oct 2024 14:50:39 +0200
Subject: [PATCH 2/9] Adding test case for builtin setjmp/longjmp.
---
.../builtin-setjmp-longjmp-alloca-00.ll | 195 ++++
.../builtin-setjmp-longjmp-alloca-01.ll | 169 +++
.../builtin-setjmp-longjmp-alloca-02.ll | 326 ++++++
.../builtin-setjmp-longjmp-alloca-03.ll | 1031 ++++++++++++++++
.../builtin-setjmp-longjmp-alloca-04.ll | 163 +++
...ltin-setjmp-longjmp-alloca-backchain-02.ll | 332 ++++++
...ltin-setjmp-longjmp-alloca-backchain-03.ll | 1037 +++++++++++++++++
.../builtin-setjmp-longjmp-backchain-03.ll | 74 ++
.../builtin-setjmp-longjmp-literal-pool-00.ll | 93 ++
.../builtin-setjmp-longjmp-literal-pool-01.ll | 202 ++++
.../builtin-setjmp-longjmp-literal-pool-02.ll | 278 +++++
.../builtin-setjmp-longjmp-literal-pool-03.ll | 416 +++++++
...etjmp-longjmp-literal-pool-backchain-00.ll | 94 ++
.../builtin-setjmp-spills-double-02.ll | 158 +++
.../builtin-setjmp-spills-double-03.ll | 227 ++++
...iltin-setjmp-spills-double-backchain-01.ll | 246 ++++
...iltin-setjmp-spills-double-backchain-02.ll | 153 +++
...iltin-setjmp-spills-double-backchain-03.ll | 225 ++++
.../SystemZ/builtin-setjmp-spills-int-02.ll | 157 +++
.../SystemZ/builtin-setjmp-spills-int-03.ll | 227 ++++
.../builtin-setjmp-spills-int-backchain-01.ll | 241 ++++
.../builtin-setjmp-spills-int-backchain-02.ll | 155 +++
.../builtin-setjmp-spills-int-backchain-03.ll | 227 ++++
23 files changed, 6426 insertions(+)
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-00.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-00.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-03.ll
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll
new file mode 100644
index 00000000000000..ec8483344109d4
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll
@@ -0,0 +1,195 @@
+; This tests Frame Pointer.
+; This test case produces Wrong result.
+; FIXME: Correct Output is:
+;First __builtin_setjmp in func1
+;Second __builtin_setjmp in func1
+;Returned from func4
+;arr: 0
+;arr: 2
+;arr: 6
+;arr: 12
+;arr: 20
+;arr: 30
+;arr: 42
+;arr: 56
+;arr: 72
+;arr: 90
+;Returned from func3
+;arr: 0
+;arr: 3
+;arr: 14
+;arr: 39
+;arr: 84
+;arr: 155
+;arr: 258
+;arr: 399
+;arr: 584
+;arr: 819
+
+; TODO: test case with -mbackchain
+
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-00.c'
+source_filename = "builtin-setjmp-longjmp-alloca-00.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %0, 0
+ br i1 %cmp3, label %if.then, label %if.else38
+
+if.then: ; preds = %entry
+ %puts77 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %1, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts78 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
+ %call18.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
+ %call18.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
+ %call18.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
+ %call18.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
+ %call18.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
+ %call18.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
+ %call18.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
+ %call18.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
+ %call18.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
+ tail call void @func3()
+ unreachable
+
+if.else38: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %call48 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
+ %call48.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
+ %call48.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
+ %call48.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
+ %call48.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
+ %call48.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
+ %call48.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
+ %call48.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
+ %call48.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
+ %call48.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll
new file mode 100644
index 00000000000000..22f35e5e2e0a08
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll
@@ -0,0 +1,169 @@
+; Producing wrong result.
+; llvm-lit does not take input from stdin, test case produces right result.
+; This test case produces right result when alloca size is unknown.
+; Test output of setjmp/longjmp with nested setjmp for alloca
+; Test for Frame Pointer in first slot in jmp_buf.
+; sum(regsiter pressure).
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-01.c'
+source_filename = "builtin-setjmp-longjmp-alloca-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %0, 0
+ br i1 %cmp3, label %if.then, label %if.else38
+
+if.then: ; preds = %entry
+ %puts77 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %1, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 3
+; CHECK: arr: 14
+; CHECK: arr: 39
+; CHECK: arr: 84
+; CHECK: arr: 155
+; CHECK: arr: 258
+; CHECK: arr: 399
+; CHECK: arr: 584
+; CHECK: arr: 819
+
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts78 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
+ %call18.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
+ %call18.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
+ %call18.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
+ %call18.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
+ %call18.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
+ %call18.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
+ %call18.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
+ %call18.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
+ %call18.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
+ tail call void @func3()
+ unreachable
+
+if.else38: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %call48 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
+ %call48.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
+ %call48.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
+ %call48.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
+ %call48.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
+ %call48.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
+ %call48.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
+ %call48.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
+ %call48.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
+ %call48.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 3
+; CHECK: arr: 14
+; CHECK: arr: 39
+; CHECK: arr: 84
+; CHECK: arr: 155
+; CHECK: arr: 258
+; CHECK: arr: 399
+; CHECK: arr: 584
+; CHECK: arr: 819
+
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll
new file mode 100644
index 00000000000000..aaf711cc512066
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll
@@ -0,0 +1,326 @@
+; Test for Frame Pointer in first slot in jmp_buf.
+; Test assembly for nested setjmp for alloa.
+; This test case takes input from stdin for size of alloca
+; and produce the right result.
+
+; RUN: llc < %s | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-01.c'
+source_filename = "builtin-setjmp-longjmp-alloca-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
+ at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
+ at .str.8 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.13 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.15 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.17 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.18 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+ %len = alloca i32, align 4
+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
+ store i32 10, ptr %len, align 4, !tbaa !4
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
+ %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
+ %0 = load i32, ptr %len, align 4, !tbaa !4
+ %conv = sext i32 %0 to i64
+ %mul = shl nsw i64 %conv, 2
+ %1 = alloca i8, i64 %mul, align 8
+ %cmp82 = icmp sgt i32 %0, 0
+ br i1 %cmp82, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %wide.trip.count = zext nneg i32 %0 to i64
+ %xtraiter = and i64 %wide.trip.count, 3
+ %2 = icmp ult i32 %0, 4
+ br i1 %2, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
+
+for.body.preheader.new: ; preds = %for.body.preheader
+ %unroll_iter = and i64 %wide.trip.count, 2147483644
+ br label %for.body
+
+for.cond.cleanup.loopexit.unr-lcssa: ; preds = %for.body, %for.body.preheader
+ %indvars.iv.unr = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next.3, %for.body ]
+ %lcmp.mod.not = icmp eq i64 %xtraiter, 0
+ br i1 %lcmp.mod.not, label %for.cond.cleanup, label %for.body.epil
+
+for.body.epil: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil
+ %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %for.body.epil ], [ %indvars.iv.unr, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
+ %indvars.epil = trunc i64 %indvars.iv.next.epil to i32
+ %3 = trunc nuw nsw i64 %indvars.iv.epil to i32
+ %add.epil = mul i32 %indvars.epil, %3
+ %arrayidx.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.epil
+ store i32 %add.epil, ptr %arrayidx.epil, align 4, !tbaa !4
+ %epil.iter.next = add i64 %epil.iter, 1
+ %epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
+ br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
+
+for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
+; CHECK: larl %r0, .LBB3_13
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r11, 0(%r1)
+; CHECK: stg %r15, 24(%r1)
+
+ %4 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp4 = icmp eq i32 %4, 0
+ br i1 %cmp4, label %if.then, label %if.else40
+
+for.body: ; preds = %for.body, %for.body.preheader.new
+ %indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
+ %niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
+ %indvars.iv.next = or disjoint i64 %indvars.iv, 1
+ %indvars = trunc i64 %indvars.iv.next to i32
+ %5 = trunc nuw nsw i64 %indvars.iv to i32
+ %add = mul i32 %indvars, %5
+ %arrayidx = getelementptr inbounds i32, ptr %1, i64 %indvars.iv
+ store i32 %add, ptr %arrayidx, align 8, !tbaa !4
+ %indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
+ %indvars.1 = trunc i64 %indvars.iv.next.1 to i32
+ %6 = trunc nuw nsw i64 %indvars.iv.next to i32
+ %add.1 = mul i32 %indvars.1, %6
+ %arrayidx.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next
+ store i32 %add.1, ptr %arrayidx.1, align 4, !tbaa !4
+ %indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
+ %indvars.2 = trunc i64 %indvars.iv.next.2 to i32
+ %7 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
+ %add.2 = mul i32 %indvars.2, %7
+ %arrayidx.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.1
+ store i32 %add.2, ptr %arrayidx.2, align 8, !tbaa !4
+ %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
+ %indvars.3 = trunc i64 %indvars.iv.next.3 to i32
+ %8 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
+ %add.3 = mul i32 %indvars.3, %8
+ %arrayidx.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.2
+ store i32 %add.3, ptr %arrayidx.3, align 4, !tbaa !4
+ %niter.next.3 = add i64 %niter, 4
+ %niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
+ br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
+
+if.then: ; preds = %for.cond.cleanup
+ %puts75 = call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %9 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp7 = icmp eq i32 %9, 0
+ br i1 %cmp7, label %if.then9, label %if.else
+
+if.then9: ; preds = %if.then
+ %puts80 = call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts76 = call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ %10 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp1486 = icmp sgt i32 %10, 0
+ br i1 %cmp1486, label %for.body17, label %for.cond.cleanup28
+
+for.cond25.preheader: ; preds = %for.body17
+ %cmp2688 = icmp sgt i32 %13, 0
+ br i1 %cmp2688, label %for.body29.preheader, label %for.cond.cleanup28
+
+for.body29.preheader: ; preds = %for.cond25.preheader
+ %wide.trip.count104 = zext nneg i32 %13 to i64
+ %xtraiter108 = and i64 %wide.trip.count104, 3
+ %11 = icmp ult i32 %13, 4
+ br i1 %11, label %for.cond.cleanup28.loopexit.unr-lcssa, label %for.body29.preheader.new
+
+for.body29.preheader.new: ; preds = %for.body29.preheader
+ %unroll_iter111 = and i64 %wide.trip.count104, 2147483644
+ br label %for.body29
+
+for.body17: ; preds = %if.else, %for.body17
+ %indvars.iv96 = phi i64 [ %indvars.iv.next97, %for.body17 ], [ 0, %if.else ]
+ %arrayidx19 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv96
+ %12 = load i32, ptr %arrayidx19, align 4, !tbaa !4
+ %call20 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %12)
+ %indvars.iv.next97 = add nuw nsw i64 %indvars.iv96, 1
+ %13 = load i32, ptr %len, align 4, !tbaa !4
+ %14 = sext i32 %13 to i64
+ %cmp14 = icmp slt i64 %indvars.iv.next97, %14
+ br i1 %cmp14, label %for.body17, label %for.cond25.preheader, !llvm.loop !12
+
+for.cond.cleanup28.loopexit.unr-lcssa: ; preds = %for.body29, %for.body29.preheader
+ %indvars.iv100.unr = phi i64 [ 0, %for.body29.preheader ], [ %indvars.iv.next101.3, %for.body29 ]
+ %lcmp.mod110.not = icmp eq i64 %xtraiter108, 0
+ br i1 %lcmp.mod110.not, label %for.cond.cleanup28, label %for.body29.epil
+
+for.body29.epil: ; preds = %for.cond.cleanup28.loopexit.unr-lcssa, %for.body29.epil
+ %indvars.iv100.epil = phi i64 [ %indvars.iv.next101.epil, %for.body29.epil ], [ %indvars.iv100.unr, %for.cond.cleanup28.loopexit.unr-lcssa ]
+ %epil.iter109 = phi i64 [ %epil.iter109.next, %for.body29.epil ], [ 0, %for.cond.cleanup28.loopexit.unr-lcssa ]
+ %indvars.iv.next101.epil = add nuw nsw i64 %indvars.iv100.epil, 1
+ %indvars102.epil = trunc i64 %indvars.iv.next101.epil to i32
+ %15 = trunc nuw nsw i64 %indvars.iv100.epil to i32
+ %mul3177.epil = mul i32 %indvars102.epil, %15
+ %add3379.epil = add nuw nsw i32 %mul3177.epil, 1
+ %add34.epil = mul i32 %add3379.epil, %15
+ %arrayidx36.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv100.epil
+ store i32 %add34.epil, ptr %arrayidx36.epil, align 4, !tbaa !4
+ %epil.iter109.next = add i64 %epil.iter109, 1
+ %epil.iter109.cmp.not = icmp eq i64 %epil.iter109.next, %xtraiter108
+ br i1 %epil.iter109.cmp.not, label %for.cond.cleanup28, label %for.body29.epil, !llvm.loop !13
+
+for.cond.cleanup28: ; preds = %for.cond.cleanup28.loopexit.unr-lcssa, %for.body29.epil, %if.else, %for.cond25.preheader
+ call void @func3()
+ unreachable
+
+for.body29: ; preds = %for.body29, %for.body29.preheader.new
+ %indvars.iv100 = phi i64 [ 0, %for.body29.preheader.new ], [ %indvars.iv.next101.3, %for.body29 ]
+ %niter112 = phi i64 [ 0, %for.body29.preheader.new ], [ %niter112.next.3, %for.body29 ]
+ %indvars.iv.next101 = or disjoint i64 %indvars.iv100, 1
+ %indvars102 = trunc i64 %indvars.iv.next101 to i32
+ %16 = trunc nuw nsw i64 %indvars.iv100 to i32
+ %mul3177 = mul i32 %indvars102, %16
+ %add3379 = or disjoint i32 %mul3177, 1
+ %add34 = mul i32 %add3379, %16
+ %arrayidx36 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv100
+ store i32 %add34, ptr %arrayidx36, align 8, !tbaa !4
+ %indvars.iv.next101.1 = or disjoint i64 %indvars.iv100, 2
+ %indvars102.1 = trunc i64 %indvars.iv.next101.1 to i32
+ %17 = trunc nuw nsw i64 %indvars.iv.next101 to i32
+ %mul3177.1 = mul i32 %indvars102.1, %17
+ %add3379.1 = or disjoint i32 %mul3177.1, 1
+ %add34.1 = mul i32 %add3379.1, %17
+ %arrayidx36.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101
+ store i32 %add34.1, ptr %arrayidx36.1, align 4, !tbaa !4
+ %indvars.iv.next101.2 = or disjoint i64 %indvars.iv100, 3
+ %indvars102.2 = trunc i64 %indvars.iv.next101.2 to i32
+ %18 = trunc nuw nsw i64 %indvars.iv.next101.1 to i32
+ %mul3177.2 = mul i32 %indvars102.2, %18
+ %add3379.2 = or disjoint i32 %mul3177.2, 1
+ %add34.2 = mul i32 %add3379.2, %18
+ %arrayidx36.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101.1
+ store i32 %add34.2, ptr %arrayidx36.2, align 8, !tbaa !4
+ %indvars.iv.next101.3 = add nuw nsw i64 %indvars.iv100, 4
+ %indvars102.3 = trunc i64 %indvars.iv.next101.3 to i32
+ %19 = trunc nuw nsw i64 %indvars.iv.next101.2 to i32
+ %mul3177.3 = mul i32 %indvars102.3, %19
+ %add3379.3 = or disjoint i32 %mul3177.3, 1
+ %add34.3 = mul i32 %add3379.3, %19
+ %arrayidx36.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101.2
+ store i32 %add34.3, ptr %arrayidx36.3, align 4, !tbaa !4
+ %niter112.next.3 = add i64 %niter112, 4
+ %niter112.ncmp.3 = icmp eq i64 %niter112.next.3, %unroll_iter111
+ br i1 %niter112.ncmp.3, label %for.cond.cleanup28.loopexit.unr-lcssa, label %for.body29, !llvm.loop !14
+
+if.else40: ; preds = %for.cond.cleanup
+ %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %20 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp4484 = icmp sgt i32 %20, 0
+ br i1 %cmp4484, label %for.body47, label %for.cond.cleanup46
+
+for.cond.cleanup46: ; preds = %for.body47, %if.else40
+ call void @func2()
+ unreachable
+
+for.body47: ; preds = %if.else40, %for.body47
+ %indvars.iv92 = phi i64 [ %indvars.iv.next93, %for.body47 ], [ 0, %if.else40 ]
+ %arrayidx49 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv92
+ %21 = load i32, ptr %arrayidx49, align 4, !tbaa !4
+ %call50 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %21)
+ %indvars.iv.next93 = add nuw nsw i64 %indvars.iv92, 1
+ %22 = load i32, ptr %len, align 4, !tbaa !4
+ %23 = sext i32 %22 to i64
+ %cmp44 = icmp slt i64 %indvars.iv.next93, %23
+ br i1 %cmp44, label %for.body47, label %for.cond.cleanup46, !llvm.loop !15
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+attributes #5 = { nounwind }
+attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = distinct !{!8, !9}
+!9 = !{!"llvm.loop.unroll.disable"}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
+!13 = distinct !{!13, !9}
+!14 = distinct !{!14, !11}
+!15 = distinct !{!15, !11}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-03.ll
new file mode 100644
index 00000000000000..d68bf7a9838489
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-03.ll
@@ -0,0 +1,1031 @@
+; Test for Frame Pointer in first slot in jmp_buf.
+; Test assembly for nested setjmp for alloa with switch statement.
+; This test case takes input from stdin for size of alloca
+; and produce the right result.
+; Frame Pointer in slot 1.
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+
+; RUN: llc < %s | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-03.c'
+source_filename = "builtin-setjmp-longjmp-alloca-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
+ at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
+ at .str.13 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.17 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.18 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.20 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.21 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.27 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.28 = private unnamed_addr constant [8 x i8] c"case 4:\00", align 1
+ at str.29 = private unnamed_addr constant [8 x i8] c"case 3:\00", align 1
+ at str.30 = private unnamed_addr constant [8 x i8] c"case 2:\00", align 1
+ at str.31 = private unnamed_addr constant [8 x i8] c"case 1:\00", align 1
+ at str.32 = private unnamed_addr constant [8 x i8] c"case 0:\00", align 1
+ at str.33 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.34 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+ %len = alloca i32, align 4
+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
+ store i32 10, ptr %len, align 4, !tbaa !4
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
+ %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
+ %0 = load i32, ptr %len, align 4, !tbaa !4
+ %conv = sext i32 %0 to i64
+ %mul = shl nsw i64 %conv, 2
+ %1 = alloca i8, i64 %mul, align 8
+ %cmp350 = icmp sgt i32 %0, 0
+ br i1 %cmp350, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %wide.trip.count = zext nneg i32 %0 to i64
+ %xtraiter = and i64 %wide.trip.count, 3
+ %2 = icmp ult i32 %0, 4
+ br i1 %2, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
+
+for.body.preheader.new: ; preds = %for.body.preheader
+ %unroll_iter = and i64 %wide.trip.count, 2147483644
+ br label %for.body
+
+for.cond.cleanup.loopexit.unr-lcssa: ; preds = %for.body, %for.body.preheader
+ %indvars.iv.unr = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next.3, %for.body ]
+ %lcmp.mod.not = icmp eq i64 %xtraiter, 0
+ br i1 %lcmp.mod.not, label %for.cond.cleanup, label %for.body.epil
+
+for.body.epil: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil
+ %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %for.body.epil ], [ %indvars.iv.unr, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
+ %indvars.epil = trunc i64 %indvars.iv.next.epil to i32
+ %3 = trunc nuw nsw i64 %indvars.iv.epil to i32
+ %add.epil = mul i32 %indvars.epil, %3
+ %arrayidx.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.epil
+ store i32 %add.epil, ptr %arrayidx.epil, align 4, !tbaa !4
+ %epil.iter.next = add i64 %epil.iter, 1
+ %epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
+ br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
+
+for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
+ %4 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp4 = icmp eq i32 %4, 0
+ br i1 %cmp4, label %if.then, label %if.else202
+
+for.body: ; preds = %for.body, %for.body.preheader.new
+ %indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
+ %niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
+ %indvars.iv.next = or disjoint i64 %indvars.iv, 1
+ %indvars = trunc i64 %indvars.iv.next to i32
+ %5 = trunc nuw nsw i64 %indvars.iv to i32
+ %add = mul i32 %indvars, %5
+ %arrayidx = getelementptr inbounds i32, ptr %1, i64 %indvars.iv
+ store i32 %add, ptr %arrayidx, align 8, !tbaa !4
+ %indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
+ %indvars.1 = trunc i64 %indvars.iv.next.1 to i32
+ %6 = trunc nuw nsw i64 %indvars.iv.next to i32
+ %add.1 = mul i32 %indvars.1, %6
+ %arrayidx.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next
+ store i32 %add.1, ptr %arrayidx.1, align 4, !tbaa !4
+ %indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
+ %indvars.2 = trunc i64 %indvars.iv.next.2 to i32
+ %7 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
+ %add.2 = mul i32 %indvars.2, %7
+ %arrayidx.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.1
+ store i32 %add.2, ptr %arrayidx.2, align 8, !tbaa !4
+ %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
+ %indvars.3 = trunc i64 %indvars.iv.next.3 to i32
+ %8 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
+ %add.3 = mul i32 %indvars.3, %8
+ %arrayidx.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.2
+ store i32 %add.3, ptr %arrayidx.3, align 4, !tbaa !4
+ %niter.next.3 = add i64 %niter, 4
+ %niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
+ br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
+
+if.then: ; preds = %for.cond.cleanup
+ %puts307 = call i32 @puts(ptr nonnull dereferenceable(1) @str.20)
+ %9 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp7 = icmp eq i32 %9, 0
+ br i1 %cmp7, label %if.then9, label %if.else
+
+if.then9: ; preds = %if.then
+ %puts324 = call i32 @puts(ptr nonnull dereferenceable(1) @str.27)
+ %10 = load i32, ptr %len, align 4, !tbaa !4
+ %rem = srem i32 %10, 5
+ switch i32 %rem, label %sw.epilog [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb26
+ i32 2, label %sw.bb45
+ i32 3, label %sw.bb63
+ i32 4, label %sw.bb79
+ ]
+
+sw.bb: ; preds = %if.then9
+ %puts339 = call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
+ %11 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp14374 = icmp sgt i32 %11, 0
+ br i1 %cmp14374, label %for.body17.preheader, label %sw.epilog
+
+for.body17.preheader: ; preds = %sw.bb
+ %wide.trip.count460 = zext nneg i32 %11 to i64
+ %xtraiter534 = and i64 %wide.trip.count460, 3
+ %12 = icmp ult i32 %11, 4
+ br i1 %12, label %sw.epilog.loopexit.unr-lcssa, label %for.body17.preheader.new
+
+for.body17.preheader.new: ; preds = %for.body17.preheader
+ %unroll_iter537 = and i64 %wide.trip.count460, 2147483644
+ br label %for.body17
+
+for.body17: ; preds = %for.body17, %for.body17.preheader.new
+ %indvars.iv455 = phi i64 [ 0, %for.body17.preheader.new ], [ %indvars.iv.next456.3, %for.body17 ]
+ %niter538 = phi i64 [ 0, %for.body17.preheader.new ], [ %niter538.next.3, %for.body17 ]
+ %indvars459 = trunc i64 %indvars.iv455 to i32
+ %mul19340 = or disjoint i32 %indvars459, 3
+ %add20 = mul i32 %mul19340, %indvars459
+ %arrayidx22 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv455
+ store i32 %add20, ptr %arrayidx22, align 8, !tbaa !4
+ %indvars.iv.next456 = or disjoint i64 %indvars.iv455, 1
+ %indvars459.1 = trunc i64 %indvars.iv.next456 to i32
+ %mul19340.1 = add nuw i32 %indvars459.1, 3
+ %add20.1 = mul i32 %mul19340.1, %indvars459.1
+ %arrayidx22.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456
+ store i32 %add20.1, ptr %arrayidx22.1, align 4, !tbaa !4
+ %indvars.iv.next456.1 = or disjoint i64 %indvars.iv455, 2
+ %indvars459.2 = trunc i64 %indvars.iv.next456.1 to i32
+ %mul19340.2 = add nuw i32 %indvars459.2, 3
+ %add20.2 = mul i32 %mul19340.2, %indvars459.2
+ %arrayidx22.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456.1
+ store i32 %add20.2, ptr %arrayidx22.2, align 8, !tbaa !4
+ %indvars.iv.next456.2 = or disjoint i64 %indvars.iv455, 3
+ %indvars459.3 = trunc i64 %indvars.iv.next456.2 to i32
+ %mul19340.3 = add nuw i32 %indvars459.3, 3
+ %add20.3 = mul i32 %mul19340.3, %indvars459.3
+ %arrayidx22.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456.2
+ store i32 %add20.3, ptr %arrayidx22.3, align 4, !tbaa !4
+ %indvars.iv.next456.3 = add nuw nsw i64 %indvars.iv455, 4
+ %niter538.next.3 = add i64 %niter538, 4
+ %niter538.ncmp.3 = icmp eq i64 %niter538.next.3, %unroll_iter537
+ br i1 %niter538.ncmp.3, label %sw.epilog.loopexit.unr-lcssa, label %for.body17, !llvm.loop !12
+
+sw.bb26: ; preds = %if.then9
+ %puts335 = call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
+ %13 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp30372 = icmp sgt i32 %13, 0
+ br i1 %cmp30372, label %for.body33.preheader, label %sw.epilog
+
+for.body33.preheader: ; preds = %sw.bb26
+ %wide.trip.count453 = zext nneg i32 %13 to i64
+ %xtraiter529 = and i64 %wide.trip.count453, 3
+ %14 = icmp ult i32 %13, 4
+ br i1 %14, label %sw.epilog.loopexit480.unr-lcssa, label %for.body33.preheader.new
+
+for.body33.preheader.new: ; preds = %for.body33.preheader
+ %unroll_iter532 = and i64 %wide.trip.count453, 2147483644
+ br label %for.body33
+
+for.body33: ; preds = %for.body33, %for.body33.preheader.new
+ %indvars.iv449 = phi i64 [ 0, %for.body33.preheader.new ], [ %indvars.iv.next450.3, %for.body33 ]
+ %niter533 = phi i64 [ 0, %for.body33.preheader.new ], [ %niter533.next.3, %for.body33 ]
+ %indvars.iv.next450 = or disjoint i64 %indvars.iv449, 1
+ %indvars451 = trunc i64 %indvars.iv.next450 to i32
+ %15 = trunc nuw nsw i64 %indvars.iv449 to i32
+ %mul35336 = mul i32 %indvars451, %15
+ %add37338 = or disjoint i32 %mul35336, 3
+ %add39 = mul i32 %add37338, %15
+ %arrayidx41 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv449
+ store i32 %add39, ptr %arrayidx41, align 8, !tbaa !4
+ %indvars.iv.next450.1 = or disjoint i64 %indvars.iv449, 2
+ %indvars451.1 = trunc i64 %indvars.iv.next450.1 to i32
+ %16 = trunc nuw nsw i64 %indvars.iv.next450 to i32
+ %mul35336.1 = mul i32 %indvars451.1, %16
+ %add37338.1 = add i32 %mul35336.1, 3
+ %add39.1 = mul i32 %add37338.1, %16
+ %arrayidx41.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450
+ store i32 %add39.1, ptr %arrayidx41.1, align 4, !tbaa !4
+ %indvars.iv.next450.2 = or disjoint i64 %indvars.iv449, 3
+ %indvars451.2 = trunc i64 %indvars.iv.next450.2 to i32
+ %17 = trunc nuw nsw i64 %indvars.iv.next450.1 to i32
+ %mul35336.2 = mul i32 %indvars451.2, %17
+ %add37338.2 = add i32 %mul35336.2, 3
+ %add39.2 = mul i32 %add37338.2, %17
+ %arrayidx41.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450.1
+ store i32 %add39.2, ptr %arrayidx41.2, align 8, !tbaa !4
+ %indvars.iv.next450.3 = add nuw nsw i64 %indvars.iv449, 4
+ %indvars451.3 = trunc i64 %indvars.iv.next450.3 to i32
+ %18 = trunc nuw nsw i64 %indvars.iv.next450.2 to i32
+ %mul35336.3 = mul i32 %indvars451.3, %18
+ %add37338.3 = or disjoint i32 %mul35336.3, 3
+ %add39.3 = mul i32 %add37338.3, %18
+ %arrayidx41.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450.2
+ store i32 %add39.3, ptr %arrayidx41.3, align 4, !tbaa !4
+ %niter533.next.3 = add i64 %niter533, 4
+ %niter533.ncmp.3 = icmp eq i64 %niter533.next.3, %unroll_iter532
+ br i1 %niter533.ncmp.3, label %sw.epilog.loopexit480.unr-lcssa, label %for.body33, !llvm.loop !13
+
+sw.bb45: ; preds = %if.then9
+ %puts331 = call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
+ %19 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp49370 = icmp sgt i32 %19, 0
+ br i1 %cmp49370, label %for.body52.preheader, label %sw.epilog
+
+for.body52.preheader: ; preds = %sw.bb45
+ %wide.trip.count447 = zext nneg i32 %19 to i64
+ %xtraiter524 = and i64 %wide.trip.count447, 3
+ %20 = icmp ult i32 %19, 4
+ br i1 %20, label %sw.epilog.loopexit481.unr-lcssa, label %for.body52.preheader.new
+
+for.body52.preheader.new: ; preds = %for.body52.preheader
+ %unroll_iter527 = and i64 %wide.trip.count447, 2147483644
+ br label %for.body52
+
+for.body52: ; preds = %for.body52, %for.body52.preheader.new
+ %indvars.iv442 = phi i64 [ 0, %for.body52.preheader.new ], [ %indvars.iv.next443.3, %for.body52 ]
+ %niter528 = phi i64 [ 0, %for.body52.preheader.new ], [ %niter528.next.3, %for.body52 ]
+ %indvars446 = trunc i64 %indvars.iv442 to i32
+ %i47.0333 = add nsw i32 %indvars446, -1
+ %mul54332 = mul i32 %i47.0333, %indvars446
+ %sub334 = or disjoint i32 %mul54332, 3
+ %add57 = mul i32 %sub334, %indvars446
+ %arrayidx59 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv442
+ store i32 %add57, ptr %arrayidx59, align 8, !tbaa !4
+ %indvars.iv.next443 = or disjoint i64 %indvars.iv442, 1
+ %indvars446.1 = trunc i64 %indvars.iv.next443 to i32
+ %i47.0333.1 = add nsw i32 %indvars446.1, -1
+ %mul54332.1 = mul i32 %i47.0333.1, %indvars446.1
+ %sub334.1 = or disjoint i32 %mul54332.1, 3
+ %add57.1 = mul i32 %sub334.1, %indvars446.1
+ %arrayidx59.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443
+ store i32 %add57.1, ptr %arrayidx59.1, align 4, !tbaa !4
+ %indvars.iv.next443.1 = or disjoint i64 %indvars.iv442, 2
+ %indvars446.2 = trunc i64 %indvars.iv.next443.1 to i32
+ %i47.0333.2 = add nsw i32 %indvars446.2, -1
+ %mul54332.2 = mul i32 %i47.0333.2, %indvars446.2
+ %sub334.2 = add i32 %mul54332.2, 3
+ %add57.2 = mul i32 %sub334.2, %indvars446.2
+ %arrayidx59.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443.1
+ store i32 %add57.2, ptr %arrayidx59.2, align 8, !tbaa !4
+ %indvars.iv.next443.2 = or disjoint i64 %indvars.iv442, 3
+ %indvars446.3 = trunc i64 %indvars.iv.next443.2 to i32
+ %i47.0333.3 = add nsw i32 %indvars446.3, -1
+ %mul54332.3 = mul i32 %i47.0333.3, %indvars446.3
+ %sub334.3 = add i32 %mul54332.3, 3
+ %add57.3 = mul i32 %sub334.3, %indvars446.3
+ %arrayidx59.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443.2
+ store i32 %add57.3, ptr %arrayidx59.3, align 4, !tbaa !4
+ %indvars.iv.next443.3 = add nuw nsw i64 %indvars.iv442, 4
+ %niter528.next.3 = add i64 %niter528, 4
+ %niter528.ncmp.3 = icmp eq i64 %niter528.next.3, %unroll_iter527
+ br i1 %niter528.ncmp.3, label %sw.epilog.loopexit481.unr-lcssa, label %for.body52, !llvm.loop !14
+
+sw.bb63: ; preds = %if.then9
+ %puts329 = call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
+ %21 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp67368 = icmp sgt i32 %21, 0
+ br i1 %cmp67368, label %for.body70.preheader, label %sw.epilog
+
+for.body70.preheader: ; preds = %sw.bb63
+ %wide.trip.count440 = zext nneg i32 %21 to i64
+ %xtraiter519 = and i64 %wide.trip.count440, 3
+ %22 = icmp ult i32 %21, 4
+ br i1 %22, label %sw.epilog.loopexit482.unr-lcssa, label %for.body70.preheader.new
+
+for.body70.preheader.new: ; preds = %for.body70.preheader
+ %unroll_iter522 = and i64 %wide.trip.count440, 2147483644
+ br label %for.body70
+
+for.body70: ; preds = %for.body70, %for.body70.preheader.new
+ %indvars.iv436 = phi i64 [ 0, %for.body70.preheader.new ], [ %indvars.iv.next437.3, %for.body70 ]
+ %niter523 = phi i64 [ 0, %for.body70.preheader.new ], [ %niter523.next.3, %for.body70 ]
+ %indvars.iv.next437 = or disjoint i64 %indvars.iv436, 1
+ %indvars438 = trunc i64 %indvars.iv.next437 to i32
+ %23 = trunc nuw nsw i64 %indvars.iv436 to i32
+ %add72 = mul i32 %indvars438, %23
+ %add73 = or disjoint i32 %add72, 3
+ %arrayidx75 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv436
+ store i32 %add73, ptr %arrayidx75, align 8, !tbaa !4
+ %indvars.iv.next437.1 = or disjoint i64 %indvars.iv436, 2
+ %indvars438.1 = trunc i64 %indvars.iv.next437.1 to i32
+ %24 = trunc nuw nsw i64 %indvars.iv.next437 to i32
+ %add72.1 = mul i32 %indvars438.1, %24
+ %add73.1 = add nsw i32 %add72.1, 3
+ %arrayidx75.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437
+ store i32 %add73.1, ptr %arrayidx75.1, align 4, !tbaa !4
+ %indvars.iv.next437.2 = or disjoint i64 %indvars.iv436, 3
+ %indvars438.2 = trunc i64 %indvars.iv.next437.2 to i32
+ %25 = trunc nuw nsw i64 %indvars.iv.next437.1 to i32
+ %add72.2 = mul i32 %indvars438.2, %25
+ %add73.2 = add nsw i32 %add72.2, 3
+ %arrayidx75.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437.1
+ store i32 %add73.2, ptr %arrayidx75.2, align 8, !tbaa !4
+ %indvars.iv.next437.3 = add nuw nsw i64 %indvars.iv436, 4
+ %indvars438.3 = trunc i64 %indvars.iv.next437.3 to i32
+ %26 = trunc nuw nsw i64 %indvars.iv.next437.2 to i32
+ %add72.3 = mul i32 %indvars438.3, %26
+ %add73.3 = or disjoint i32 %add72.3, 3
+ %arrayidx75.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437.2
+ store i32 %add73.3, ptr %arrayidx75.3, align 4, !tbaa !4
+ %niter523.next.3 = add i64 %niter523, 4
+ %niter523.ncmp.3 = icmp eq i64 %niter523.next.3, %unroll_iter522
+ br i1 %niter523.ncmp.3, label %sw.epilog.loopexit482.unr-lcssa, label %for.body70, !llvm.loop !15
+
+sw.bb79: ; preds = %if.then9
+ %puts325 = call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
+ %27 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp83366 = icmp sgt i32 %27, 0
+ br i1 %cmp83366, label %for.body86.preheader, label %sw.epilog
+
+for.body86.preheader: ; preds = %sw.bb79
+ %wide.trip.count434 = zext nneg i32 %27 to i64
+ %xtraiter514 = and i64 %wide.trip.count434, 3
+ %28 = icmp ult i32 %27, 4
+ br i1 %28, label %sw.epilog.loopexit483.unr-lcssa, label %for.body86.preheader.new
+
+for.body86.preheader.new: ; preds = %for.body86.preheader
+ %unroll_iter517 = and i64 %wide.trip.count434, 2147483644
+ br label %for.body86
+
+for.body86: ; preds = %for.body86, %for.body86.preheader.new
+ %indvars.iv428 = phi i64 [ 0, %for.body86.preheader.new ], [ %indvars.iv.next429.3, %for.body86 ]
+ %niter518 = phi i64 [ 0, %for.body86.preheader.new ], [ %niter518.next.3, %for.body86 ]
+ %indvars433 = trunc i64 %indvars.iv428 to i32
+ %mul87 = mul nuw nsw i32 %indvars433, %indvars433
+ %mul88327 = or disjoint i32 %mul87, 1
+ %mul89326 = mul i32 %mul88327, %indvars433
+ %add91328 = or disjoint i32 %mul89326, 3
+ %add93 = mul i32 %add91328, %indvars433
+ %arrayidx95 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv428
+ store i32 %add93, ptr %arrayidx95, align 8, !tbaa !4
+ %indvars.iv.next429 = or disjoint i64 %indvars.iv428, 1
+ %indvars433.1 = trunc i64 %indvars.iv.next429 to i32
+ %mul87.1 = mul nuw nsw i32 %indvars433.1, %indvars433.1
+ %mul88327.1 = add nuw nsw i32 %mul87.1, 1
+ %mul89326.1 = mul i32 %mul88327.1, %indvars433.1
+ %add91328.1 = add i32 %mul89326.1, 3
+ %add93.1 = mul i32 %add91328.1, %indvars433.1
+ %arrayidx95.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429
+ store i32 %add93.1, ptr %arrayidx95.1, align 4, !tbaa !4
+ %indvars.iv.next429.1 = or disjoint i64 %indvars.iv428, 2
+ %indvars433.2 = trunc i64 %indvars.iv.next429.1 to i32
+ %mul87.2 = mul nuw nsw i32 %indvars433.2, %indvars433.2
+ %mul88327.2 = or disjoint i32 %mul87.2, 1
+ %mul89326.2 = mul i32 %mul88327.2, %indvars433.2
+ %add91328.2 = add i32 %mul89326.2, 3
+ %add93.2 = mul i32 %add91328.2, %indvars433.2
+ %arrayidx95.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429.1
+ store i32 %add93.2, ptr %arrayidx95.2, align 8, !tbaa !4
+ %indvars.iv.next429.2 = or disjoint i64 %indvars.iv428, 3
+ %indvars433.3 = trunc i64 %indvars.iv.next429.2 to i32
+ %mul87.3 = mul nuw nsw i32 %indvars433.3, %indvars433.3
+ %mul88327.3 = add nuw nsw i32 %mul87.3, 1
+ %mul89326.3 = mul i32 %mul88327.3, %indvars433.3
+ %add91328.3 = add i32 %mul89326.3, 3
+ %add93.3 = mul i32 %add91328.3, %indvars433.3
+ %arrayidx95.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429.2
+ store i32 %add93.3, ptr %arrayidx95.3, align 4, !tbaa !4
+ %indvars.iv.next429.3 = add nuw nsw i64 %indvars.iv428, 4
+ %niter518.next.3 = add i64 %niter518, 4
+ %niter518.ncmp.3 = icmp eq i64 %niter518.next.3, %unroll_iter517
+ br i1 %niter518.ncmp.3, label %sw.epilog.loopexit483.unr-lcssa, label %for.body86, !llvm.loop !16
+
+sw.epilog.loopexit.unr-lcssa: ; preds = %for.body17, %for.body17.preheader
+ %indvars.iv455.unr = phi i64 [ 0, %for.body17.preheader ], [ %indvars.iv.next456.3, %for.body17 ]
+ %lcmp.mod536.not = icmp eq i64 %xtraiter534, 0
+ br i1 %lcmp.mod536.not, label %sw.epilog, label %for.body17.epil
+
+for.body17.epil: ; preds = %sw.epilog.loopexit.unr-lcssa, %for.body17.epil
+ %indvars.iv455.epil = phi i64 [ %indvars.iv.next456.epil, %for.body17.epil ], [ %indvars.iv455.unr, %sw.epilog.loopexit.unr-lcssa ]
+ %epil.iter535 = phi i64 [ %epil.iter535.next, %for.body17.epil ], [ 0, %sw.epilog.loopexit.unr-lcssa ]
+ %indvars459.epil = trunc i64 %indvars.iv455.epil to i32
+ %mul19340.epil = add nuw i32 %indvars459.epil, 3
+ %add20.epil = mul i32 %mul19340.epil, %indvars459.epil
+ %arrayidx22.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv455.epil
+ store i32 %add20.epil, ptr %arrayidx22.epil, align 4, !tbaa !4
+ %indvars.iv.next456.epil = add nuw nsw i64 %indvars.iv455.epil, 1
+ %epil.iter535.next = add i64 %epil.iter535, 1
+ %epil.iter535.cmp.not = icmp eq i64 %epil.iter535.next, %xtraiter534
+ br i1 %epil.iter535.cmp.not, label %sw.epilog, label %for.body17.epil, !llvm.loop !17
+
+sw.epilog.loopexit480.unr-lcssa: ; preds = %for.body33, %for.body33.preheader
+ %indvars.iv449.unr = phi i64 [ 0, %for.body33.preheader ], [ %indvars.iv.next450.3, %for.body33 ]
+ %lcmp.mod531.not = icmp eq i64 %xtraiter529, 0
+ br i1 %lcmp.mod531.not, label %sw.epilog, label %for.body33.epil
+
+for.body33.epil: ; preds = %sw.epilog.loopexit480.unr-lcssa, %for.body33.epil
+ %indvars.iv449.epil = phi i64 [ %indvars.iv.next450.epil, %for.body33.epil ], [ %indvars.iv449.unr, %sw.epilog.loopexit480.unr-lcssa ]
+ %epil.iter530 = phi i64 [ %epil.iter530.next, %for.body33.epil ], [ 0, %sw.epilog.loopexit480.unr-lcssa ]
+ %indvars.iv.next450.epil = add nuw nsw i64 %indvars.iv449.epil, 1
+ %indvars451.epil = trunc i64 %indvars.iv.next450.epil to i32
+ %29 = trunc nuw nsw i64 %indvars.iv449.epil to i32
+ %mul35336.epil = mul i32 %indvars451.epil, %29
+ %add37338.epil = add i32 %mul35336.epil, 3
+ %add39.epil = mul i32 %add37338.epil, %29
+ %arrayidx41.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv449.epil
+ store i32 %add39.epil, ptr %arrayidx41.epil, align 4, !tbaa !4
+ %epil.iter530.next = add i64 %epil.iter530, 1
+ %epil.iter530.cmp.not = icmp eq i64 %epil.iter530.next, %xtraiter529
+ br i1 %epil.iter530.cmp.not, label %sw.epilog, label %for.body33.epil, !llvm.loop !18
+
+sw.epilog.loopexit481.unr-lcssa: ; preds = %for.body52, %for.body52.preheader
+ %indvars.iv442.unr = phi i64 [ 0, %for.body52.preheader ], [ %indvars.iv.next443.3, %for.body52 ]
+ %lcmp.mod526.not = icmp eq i64 %xtraiter524, 0
+ br i1 %lcmp.mod526.not, label %sw.epilog, label %for.body52.epil
+
+for.body52.epil: ; preds = %sw.epilog.loopexit481.unr-lcssa, %for.body52.epil
+ %indvars.iv442.epil = phi i64 [ %indvars.iv.next443.epil, %for.body52.epil ], [ %indvars.iv442.unr, %sw.epilog.loopexit481.unr-lcssa ]
+ %epil.iter525 = phi i64 [ %epil.iter525.next, %for.body52.epil ], [ 0, %sw.epilog.loopexit481.unr-lcssa ]
+ %indvars446.epil = trunc i64 %indvars.iv442.epil to i32
+ %i47.0333.epil = add nsw i32 %indvars446.epil, -1
+ %mul54332.epil = mul i32 %i47.0333.epil, %indvars446.epil
+ %sub334.epil = add i32 %mul54332.epil, 3
+ %add57.epil = mul i32 %sub334.epil, %indvars446.epil
+ %arrayidx59.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv442.epil
+ store i32 %add57.epil, ptr %arrayidx59.epil, align 4, !tbaa !4
+ %indvars.iv.next443.epil = add nuw nsw i64 %indvars.iv442.epil, 1
+ %epil.iter525.next = add i64 %epil.iter525, 1
+ %epil.iter525.cmp.not = icmp eq i64 %epil.iter525.next, %xtraiter524
+ br i1 %epil.iter525.cmp.not, label %sw.epilog, label %for.body52.epil, !llvm.loop !19
+
+sw.epilog.loopexit482.unr-lcssa: ; preds = %for.body70, %for.body70.preheader
+ %indvars.iv436.unr = phi i64 [ 0, %for.body70.preheader ], [ %indvars.iv.next437.3, %for.body70 ]
+ %lcmp.mod521.not = icmp eq i64 %xtraiter519, 0
+ br i1 %lcmp.mod521.not, label %sw.epilog, label %for.body70.epil
+
+for.body70.epil: ; preds = %sw.epilog.loopexit482.unr-lcssa, %for.body70.epil
+ %indvars.iv436.epil = phi i64 [ %indvars.iv.next437.epil, %for.body70.epil ], [ %indvars.iv436.unr, %sw.epilog.loopexit482.unr-lcssa ]
+ %epil.iter520 = phi i64 [ %epil.iter520.next, %for.body70.epil ], [ 0, %sw.epilog.loopexit482.unr-lcssa ]
+ %indvars.iv.next437.epil = add nuw nsw i64 %indvars.iv436.epil, 1
+ %indvars438.epil = trunc i64 %indvars.iv.next437.epil to i32
+ %30 = trunc nuw nsw i64 %indvars.iv436.epil to i32
+ %add72.epil = mul i32 %indvars438.epil, %30
+ %add73.epil = add nsw i32 %add72.epil, 3
+ %arrayidx75.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv436.epil
+ store i32 %add73.epil, ptr %arrayidx75.epil, align 4, !tbaa !4
+ %epil.iter520.next = add i64 %epil.iter520, 1
+ %epil.iter520.cmp.not = icmp eq i64 %epil.iter520.next, %xtraiter519
+ br i1 %epil.iter520.cmp.not, label %sw.epilog, label %for.body70.epil, !llvm.loop !20
+
+sw.epilog.loopexit483.unr-lcssa: ; preds = %for.body86, %for.body86.preheader
+ %indvars.iv428.unr = phi i64 [ 0, %for.body86.preheader ], [ %indvars.iv.next429.3, %for.body86 ]
+ %lcmp.mod516.not = icmp eq i64 %xtraiter514, 0
+ br i1 %lcmp.mod516.not, label %sw.epilog, label %for.body86.epil
+
+for.body86.epil: ; preds = %sw.epilog.loopexit483.unr-lcssa, %for.body86.epil
+ %indvars.iv428.epil = phi i64 [ %indvars.iv.next429.epil, %for.body86.epil ], [ %indvars.iv428.unr, %sw.epilog.loopexit483.unr-lcssa ]
+ %epil.iter515 = phi i64 [ %epil.iter515.next, %for.body86.epil ], [ 0, %sw.epilog.loopexit483.unr-lcssa ]
+ %indvars433.epil = trunc i64 %indvars.iv428.epil to i32
+ %mul87.epil = mul nuw nsw i32 %indvars433.epil, %indvars433.epil
+ %mul88327.epil = add nuw i32 %mul87.epil, 1
+ %mul89326.epil = mul i32 %mul88327.epil, %indvars433.epil
+ %add91328.epil = add i32 %mul89326.epil, 3
+ %add93.epil = mul i32 %add91328.epil, %indvars433.epil
+ %arrayidx95.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv428.epil
+ store i32 %add93.epil, ptr %arrayidx95.epil, align 4, !tbaa !4
+ %indvars.iv.next429.epil = add nuw nsw i64 %indvars.iv428.epil, 1
+ %epil.iter515.next = add i64 %epil.iter515, 1
+ %epil.iter515.cmp.not = icmp eq i64 %epil.iter515.next, %xtraiter514
+ br i1 %epil.iter515.cmp.not, label %sw.epilog, label %for.body86.epil, !llvm.loop !21
+
+sw.epilog: ; preds = %sw.epilog.loopexit483.unr-lcssa, %for.body86.epil, %sw.epilog.loopexit482.unr-lcssa, %for.body70.epil, %sw.epilog.loopexit481.unr-lcssa, %for.body52.epil, %sw.epilog.loopexit480.unr-lcssa, %for.body33.epil, %sw.epilog.loopexit.unr-lcssa, %for.body17.epil, %sw.bb79, %sw.bb63, %sw.bb45, %sw.bb26, %sw.bb, %if.then9
+ call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts308 = call i32 @puts(ptr nonnull dereferenceable(1) @str.21)
+ %31 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp102354 = icmp sgt i32 %31, 0
+ br i1 %cmp102354, label %for.body105, label %for.cond.cleanup104
+
+for.cond.cleanup104: ; preds = %for.body105, %if.else
+ %.lcssa = phi i32 [ %31, %if.else ], [ %33, %for.body105 ]
+ %rem112 = srem i32 %.lcssa, 5
+ switch i32 %rem112, label %sw.epilog201 [
+ i32 0, label %sw.bb113
+ i32 1, label %sw.bb133
+ i32 2, label %sw.bb149
+ i32 3, label %sw.bb166
+ i32 4, label %sw.bb185
+ ]
+
+for.body105: ; preds = %if.else, %for.body105
+ %indvars.iv390 = phi i64 [ %indvars.iv.next391, %for.body105 ], [ 0, %if.else ]
+ %arrayidx107 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv390
+ %32 = load i32, ptr %arrayidx107, align 4, !tbaa !4
+ %call108 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %32)
+ %indvars.iv.next391 = add nuw nsw i64 %indvars.iv390, 1
+ %33 = load i32, ptr %len, align 4, !tbaa !4
+ %34 = sext i32 %33 to i64
+ %cmp102 = icmp slt i64 %indvars.iv.next391, %34
+ br i1 %cmp102, label %for.body105, label %for.cond.cleanup104, !llvm.loop !22
+
+sw.bb113: ; preds = %for.cond.cleanup104
+ %puts320 = call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
+ %35 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp117364 = icmp sgt i32 %35, 0
+ br i1 %cmp117364, label %for.body120.preheader, label %sw.epilog201
+
+for.body120.preheader: ; preds = %sw.bb113
+ %wide.trip.count426 = zext nneg i32 %35 to i64
+ %xtraiter509 = and i64 %wide.trip.count426, 3
+ %36 = icmp ult i32 %35, 4
+ br i1 %36, label %sw.epilog201.loopexit.unr-lcssa, label %for.body120.preheader.new
+
+for.body120.preheader.new: ; preds = %for.body120.preheader
+ %unroll_iter512 = and i64 %wide.trip.count426, 2147483644
+ br label %for.body120
+
+for.body120: ; preds = %for.body120, %for.body120.preheader.new
+ %indvars.iv420 = phi i64 [ 0, %for.body120.preheader.new ], [ %indvars.iv.next421.3, %for.body120 ]
+ %niter513 = phi i64 [ 0, %for.body120.preheader.new ], [ %niter513.next.3, %for.body120 ]
+ %indvars425 = trunc i64 %indvars.iv420 to i32
+ %mul121 = mul nuw nsw i32 %indvars425, %indvars425
+ %mul122322 = or disjoint i32 %mul121, 1
+ %mul123321 = mul i32 %mul122322, %indvars425
+ %add125323 = or disjoint i32 %mul123321, 3
+ %add127 = mul i32 %add125323, %indvars425
+ %arrayidx129 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv420
+ store i32 %add127, ptr %arrayidx129, align 8, !tbaa !4
+ %indvars.iv.next421 = or disjoint i64 %indvars.iv420, 1
+ %indvars425.1 = trunc i64 %indvars.iv.next421 to i32
+ %mul121.1 = mul nuw nsw i32 %indvars425.1, %indvars425.1
+ %mul122322.1 = add nuw nsw i32 %mul121.1, 1
+ %mul123321.1 = mul i32 %mul122322.1, %indvars425.1
+ %add125323.1 = add i32 %mul123321.1, 3
+ %add127.1 = mul i32 %add125323.1, %indvars425.1
+ %arrayidx129.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421
+ store i32 %add127.1, ptr %arrayidx129.1, align 4, !tbaa !4
+ %indvars.iv.next421.1 = or disjoint i64 %indvars.iv420, 2
+ %indvars425.2 = trunc i64 %indvars.iv.next421.1 to i32
+ %mul121.2 = mul nuw nsw i32 %indvars425.2, %indvars425.2
+ %mul122322.2 = or disjoint i32 %mul121.2, 1
+ %mul123321.2 = mul i32 %mul122322.2, %indvars425.2
+ %add125323.2 = add i32 %mul123321.2, 3
+ %add127.2 = mul i32 %add125323.2, %indvars425.2
+ %arrayidx129.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421.1
+ store i32 %add127.2, ptr %arrayidx129.2, align 8, !tbaa !4
+ %indvars.iv.next421.2 = or disjoint i64 %indvars.iv420, 3
+ %indvars425.3 = trunc i64 %indvars.iv.next421.2 to i32
+ %mul121.3 = mul nuw nsw i32 %indvars425.3, %indvars425.3
+ %mul122322.3 = add nuw nsw i32 %mul121.3, 1
+ %mul123321.3 = mul i32 %mul122322.3, %indvars425.3
+ %add125323.3 = add i32 %mul123321.3, 3
+ %add127.3 = mul i32 %add125323.3, %indvars425.3
+ %arrayidx129.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421.2
+ store i32 %add127.3, ptr %arrayidx129.3, align 4, !tbaa !4
+ %indvars.iv.next421.3 = add nuw nsw i64 %indvars.iv420, 4
+ %niter513.next.3 = add i64 %niter513, 4
+ %niter513.ncmp.3 = icmp eq i64 %niter513.next.3, %unroll_iter512
+ br i1 %niter513.ncmp.3, label %sw.epilog201.loopexit.unr-lcssa, label %for.body120, !llvm.loop !23
+
+sw.bb133: ; preds = %for.cond.cleanup104
+ %puts318 = call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
+ %37 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp137362 = icmp sgt i32 %37, 0
+ br i1 %cmp137362, label %for.body140.preheader, label %sw.epilog201
+
+for.body140.preheader: ; preds = %sw.bb133
+ %wide.trip.count418 = zext nneg i32 %37 to i64
+ %xtraiter504 = and i64 %wide.trip.count418, 3
+ %38 = icmp ult i32 %37, 4
+ br i1 %38, label %sw.epilog201.loopexit484.unr-lcssa, label %for.body140.preheader.new
+
+for.body140.preheader.new: ; preds = %for.body140.preheader
+ %unroll_iter507 = and i64 %wide.trip.count418, 2147483644
+ br label %for.body140
+
+for.body140: ; preds = %for.body140, %for.body140.preheader.new
+ %indvars.iv414 = phi i64 [ 0, %for.body140.preheader.new ], [ %indvars.iv.next415.3, %for.body140 ]
+ %niter508 = phi i64 [ 0, %for.body140.preheader.new ], [ %niter508.next.3, %for.body140 ]
+ %indvars.iv.next415 = or disjoint i64 %indvars.iv414, 1
+ %indvars416 = trunc i64 %indvars.iv.next415 to i32
+ %39 = trunc nuw nsw i64 %indvars.iv414 to i32
+ %add142 = mul i32 %indvars416, %39
+ %add143 = or disjoint i32 %add142, 3
+ %arrayidx145 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv414
+ store i32 %add143, ptr %arrayidx145, align 8, !tbaa !4
+ %indvars.iv.next415.1 = or disjoint i64 %indvars.iv414, 2
+ %indvars416.1 = trunc i64 %indvars.iv.next415.1 to i32
+ %40 = trunc nuw nsw i64 %indvars.iv.next415 to i32
+ %add142.1 = mul i32 %indvars416.1, %40
+ %add143.1 = add nsw i32 %add142.1, 3
+ %arrayidx145.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415
+ store i32 %add143.1, ptr %arrayidx145.1, align 4, !tbaa !4
+ %indvars.iv.next415.2 = or disjoint i64 %indvars.iv414, 3
+ %indvars416.2 = trunc i64 %indvars.iv.next415.2 to i32
+ %41 = trunc nuw nsw i64 %indvars.iv.next415.1 to i32
+ %add142.2 = mul i32 %indvars416.2, %41
+ %add143.2 = add nsw i32 %add142.2, 3
+ %arrayidx145.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415.1
+ store i32 %add143.2, ptr %arrayidx145.2, align 8, !tbaa !4
+ %indvars.iv.next415.3 = add nuw nsw i64 %indvars.iv414, 4
+ %indvars416.3 = trunc i64 %indvars.iv.next415.3 to i32
+ %42 = trunc nuw nsw i64 %indvars.iv.next415.2 to i32
+ %add142.3 = mul i32 %indvars416.3, %42
+ %add143.3 = or disjoint i32 %add142.3, 3
+ %arrayidx145.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415.2
+ store i32 %add143.3, ptr %arrayidx145.3, align 4, !tbaa !4
+ %niter508.next.3 = add i64 %niter508, 4
+ %niter508.ncmp.3 = icmp eq i64 %niter508.next.3, %unroll_iter507
+ br i1 %niter508.ncmp.3, label %sw.epilog201.loopexit484.unr-lcssa, label %for.body140, !llvm.loop !24
+
+sw.bb149: ; preds = %for.cond.cleanup104
+ %puts315 = call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
+ %43 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp153360 = icmp sgt i32 %43, 0
+ br i1 %cmp153360, label %for.body156.preheader, label %sw.epilog201
+
+for.body156.preheader: ; preds = %sw.bb149
+ %wide.trip.count412 = zext nneg i32 %43 to i64
+ %xtraiter499 = and i64 %wide.trip.count412, 3
+ %44 = icmp ult i32 %43, 4
+ br i1 %44, label %sw.epilog201.loopexit485.unr-lcssa, label %for.body156.preheader.new
+
+for.body156.preheader.new: ; preds = %for.body156.preheader
+ %unroll_iter502 = and i64 %wide.trip.count412, 2147483644
+ br label %for.body156
+
+for.body156: ; preds = %for.body156, %for.body156.preheader.new
+ %indvars.iv407 = phi i64 [ 0, %for.body156.preheader.new ], [ %indvars.iv.next408.3, %for.body156 ]
+ %niter503 = phi i64 [ 0, %for.body156.preheader.new ], [ %niter503.next.3, %for.body156 ]
+ %45 = trunc nuw nsw i64 %indvars.iv407 to i32
+ %mul158316 = mul i32 %45, %45
+ %46 = trunc i64 %indvars.iv407 to i32
+ %47 = add i32 %46, -1
+ %sub160 = mul i32 %mul158316, %47
+ %arrayidx162 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv407
+ store i32 %sub160, ptr %arrayidx162, align 8, !tbaa !4
+ %indvars.iv.next408 = or disjoint i64 %indvars.iv407, 1
+ %48 = trunc nuw nsw i64 %indvars.iv.next408 to i32
+ %mul158316.1 = mul i32 %48, %48
+ %49 = trunc i64 %indvars.iv.next408 to i32
+ %50 = add nsw i32 %49, -1
+ %sub160.1 = mul i32 %mul158316.1, %50
+ %arrayidx162.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408
+ store i32 %sub160.1, ptr %arrayidx162.1, align 4, !tbaa !4
+ %indvars.iv.next408.1 = or disjoint i64 %indvars.iv407, 2
+ %51 = trunc nuw nsw i64 %indvars.iv.next408.1 to i32
+ %mul158316.2 = mul i32 %51, %51
+ %52 = trunc i64 %indvars.iv.next408.1 to i32
+ %53 = add nsw i32 %52, -1
+ %sub160.2 = mul i32 %mul158316.2, %53
+ %arrayidx162.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408.1
+ store i32 %sub160.2, ptr %arrayidx162.2, align 8, !tbaa !4
+ %indvars.iv.next408.2 = or disjoint i64 %indvars.iv407, 3
+ %54 = trunc nuw nsw i64 %indvars.iv.next408.2 to i32
+ %mul158316.3 = mul i32 %54, %54
+ %55 = trunc i64 %indvars.iv.next408.2 to i32
+ %56 = add nsw i32 %55, -1
+ %sub160.3 = mul i32 %mul158316.3, %56
+ %arrayidx162.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408.2
+ store i32 %sub160.3, ptr %arrayidx162.3, align 4, !tbaa !4
+ %indvars.iv.next408.3 = add nuw nsw i64 %indvars.iv407, 4
+ %niter503.next.3 = add i64 %niter503, 4
+ %niter503.ncmp.3 = icmp eq i64 %niter503.next.3, %unroll_iter502
+ br i1 %niter503.ncmp.3, label %sw.epilog201.loopexit485.unr-lcssa, label %for.body156, !llvm.loop !25
+
+sw.bb166: ; preds = %for.cond.cleanup104
+ %puts311 = call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
+ %57 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp170358 = icmp sgt i32 %57, 0
+ br i1 %cmp170358, label %for.body173.preheader, label %sw.epilog201
+
+for.body173.preheader: ; preds = %sw.bb166
+ %wide.trip.count405 = zext nneg i32 %57 to i64
+ %xtraiter494 = and i64 %wide.trip.count405, 3
+ %58 = icmp ult i32 %57, 4
+ br i1 %58, label %sw.epilog201.loopexit486.unr-lcssa, label %for.body173.preheader.new
+
+for.body173.preheader.new: ; preds = %for.body173.preheader
+ %unroll_iter497 = and i64 %wide.trip.count405, 2147483644
+ br label %for.body173
+
+for.body173: ; preds = %for.body173, %for.body173.preheader.new
+ %indvars.iv401 = phi i64 [ 0, %for.body173.preheader.new ], [ %indvars.iv.next402.3, %for.body173 ]
+ %niter498 = phi i64 [ 0, %for.body173.preheader.new ], [ %niter498.next.3, %for.body173 ]
+ %indvars.iv.next402 = or disjoint i64 %indvars.iv401, 1
+ %indvars403 = trunc i64 %indvars.iv.next402 to i32
+ %59 = trunc nuw nsw i64 %indvars.iv401 to i32
+ %mul175312 = mul i32 %indvars403, %59
+ %add177314 = or disjoint i32 %mul175312, 3
+ %add179 = mul i32 %add177314, %59
+ %arrayidx181 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv401
+ store i32 %add179, ptr %arrayidx181, align 8, !tbaa !4
+ %indvars.iv.next402.1 = or disjoint i64 %indvars.iv401, 2
+ %indvars403.1 = trunc i64 %indvars.iv.next402.1 to i32
+ %60 = trunc nuw nsw i64 %indvars.iv.next402 to i32
+ %mul175312.1 = mul i32 %indvars403.1, %60
+ %add177314.1 = add i32 %mul175312.1, 3
+ %add179.1 = mul i32 %add177314.1, %60
+ %arrayidx181.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402
+ store i32 %add179.1, ptr %arrayidx181.1, align 4, !tbaa !4
+ %indvars.iv.next402.2 = or disjoint i64 %indvars.iv401, 3
+ %indvars403.2 = trunc i64 %indvars.iv.next402.2 to i32
+ %61 = trunc nuw nsw i64 %indvars.iv.next402.1 to i32
+ %mul175312.2 = mul i32 %indvars403.2, %61
+ %add177314.2 = add i32 %mul175312.2, 3
+ %add179.2 = mul i32 %add177314.2, %61
+ %arrayidx181.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402.1
+ store i32 %add179.2, ptr %arrayidx181.2, align 8, !tbaa !4
+ %indvars.iv.next402.3 = add nuw nsw i64 %indvars.iv401, 4
+ %indvars403.3 = trunc i64 %indvars.iv.next402.3 to i32
+ %62 = trunc nuw nsw i64 %indvars.iv.next402.2 to i32
+ %mul175312.3 = mul i32 %indvars403.3, %62
+ %add177314.3 = or disjoint i32 %mul175312.3, 3
+ %add179.3 = mul i32 %add177314.3, %62
+ %arrayidx181.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402.2
+ store i32 %add179.3, ptr %arrayidx181.3, align 4, !tbaa !4
+ %niter498.next.3 = add i64 %niter498, 4
+ %niter498.ncmp.3 = icmp eq i64 %niter498.next.3, %unroll_iter497
+ br i1 %niter498.ncmp.3, label %sw.epilog201.loopexit486.unr-lcssa, label %for.body173, !llvm.loop !26
+
+sw.bb185: ; preds = %for.cond.cleanup104
+ %puts309 = call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
+ %63 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp189356 = icmp sgt i32 %63, 0
+ br i1 %cmp189356, label %for.body192.preheader, label %sw.epilog201
+
+for.body192.preheader: ; preds = %sw.bb185
+ %wide.trip.count399 = zext nneg i32 %63 to i64
+ %xtraiter489 = and i64 %wide.trip.count399, 3
+ %64 = icmp ult i32 %63, 4
+ br i1 %64, label %sw.epilog201.loopexit487.unr-lcssa, label %for.body192.preheader.new
+
+for.body192.preheader.new: ; preds = %for.body192.preheader
+ %unroll_iter492 = and i64 %wide.trip.count399, 2147483644
+ br label %for.body192
+
+for.body192: ; preds = %for.body192, %for.body192.preheader.new
+ %indvars.iv394 = phi i64 [ 0, %for.body192.preheader.new ], [ %indvars.iv.next395.3, %for.body192 ]
+ %niter493 = phi i64 [ 0, %for.body192.preheader.new ], [ %niter493.next.3, %for.body192 ]
+ %indvars398 = trunc i64 %indvars.iv394 to i32
+ %mul194310 = or disjoint i32 %indvars398, 3
+ %add195 = mul i32 %mul194310, %indvars398
+ %arrayidx197 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv394
+ store i32 %add195, ptr %arrayidx197, align 8, !tbaa !4
+ %indvars.iv.next395 = or disjoint i64 %indvars.iv394, 1
+ %indvars398.1 = trunc i64 %indvars.iv.next395 to i32
+ %mul194310.1 = add nuw i32 %indvars398.1, 3
+ %add195.1 = mul i32 %mul194310.1, %indvars398.1
+ %arrayidx197.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395
+ store i32 %add195.1, ptr %arrayidx197.1, align 4, !tbaa !4
+ %indvars.iv.next395.1 = or disjoint i64 %indvars.iv394, 2
+ %indvars398.2 = trunc i64 %indvars.iv.next395.1 to i32
+ %mul194310.2 = add nuw i32 %indvars398.2, 3
+ %add195.2 = mul i32 %mul194310.2, %indvars398.2
+ %arrayidx197.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395.1
+ store i32 %add195.2, ptr %arrayidx197.2, align 8, !tbaa !4
+ %indvars.iv.next395.2 = or disjoint i64 %indvars.iv394, 3
+ %indvars398.3 = trunc i64 %indvars.iv.next395.2 to i32
+ %mul194310.3 = add nuw i32 %indvars398.3, 3
+ %add195.3 = mul i32 %mul194310.3, %indvars398.3
+ %arrayidx197.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395.2
+ store i32 %add195.3, ptr %arrayidx197.3, align 4, !tbaa !4
+ %indvars.iv.next395.3 = add nuw nsw i64 %indvars.iv394, 4
+ %niter493.next.3 = add i64 %niter493, 4
+ %niter493.ncmp.3 = icmp eq i64 %niter493.next.3, %unroll_iter492
+ br i1 %niter493.ncmp.3, label %sw.epilog201.loopexit487.unr-lcssa, label %for.body192, !llvm.loop !27
+
+sw.epilog201.loopexit.unr-lcssa: ; preds = %for.body120, %for.body120.preheader
+ %indvars.iv420.unr = phi i64 [ 0, %for.body120.preheader ], [ %indvars.iv.next421.3, %for.body120 ]
+ %lcmp.mod511.not = icmp eq i64 %xtraiter509, 0
+ br i1 %lcmp.mod511.not, label %sw.epilog201, label %for.body120.epil
+
+for.body120.epil: ; preds = %sw.epilog201.loopexit.unr-lcssa, %for.body120.epil
+ %indvars.iv420.epil = phi i64 [ %indvars.iv.next421.epil, %for.body120.epil ], [ %indvars.iv420.unr, %sw.epilog201.loopexit.unr-lcssa ]
+ %epil.iter510 = phi i64 [ %epil.iter510.next, %for.body120.epil ], [ 0, %sw.epilog201.loopexit.unr-lcssa ]
+ %indvars425.epil = trunc i64 %indvars.iv420.epil to i32
+ %mul121.epil = mul nuw nsw i32 %indvars425.epil, %indvars425.epil
+ %mul122322.epil = add nuw i32 %mul121.epil, 1
+ %mul123321.epil = mul i32 %mul122322.epil, %indvars425.epil
+ %add125323.epil = add i32 %mul123321.epil, 3
+ %add127.epil = mul i32 %add125323.epil, %indvars425.epil
+ %arrayidx129.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv420.epil
+ store i32 %add127.epil, ptr %arrayidx129.epil, align 4, !tbaa !4
+ %indvars.iv.next421.epil = add nuw nsw i64 %indvars.iv420.epil, 1
+ %epil.iter510.next = add i64 %epil.iter510, 1
+ %epil.iter510.cmp.not = icmp eq i64 %epil.iter510.next, %xtraiter509
+ br i1 %epil.iter510.cmp.not, label %sw.epilog201, label %for.body120.epil, !llvm.loop !28
+
+sw.epilog201.loopexit484.unr-lcssa: ; preds = %for.body140, %for.body140.preheader
+ %indvars.iv414.unr = phi i64 [ 0, %for.body140.preheader ], [ %indvars.iv.next415.3, %for.body140 ]
+ %lcmp.mod506.not = icmp eq i64 %xtraiter504, 0
+ br i1 %lcmp.mod506.not, label %sw.epilog201, label %for.body140.epil
+
+for.body140.epil: ; preds = %sw.epilog201.loopexit484.unr-lcssa, %for.body140.epil
+ %indvars.iv414.epil = phi i64 [ %indvars.iv.next415.epil, %for.body140.epil ], [ %indvars.iv414.unr, %sw.epilog201.loopexit484.unr-lcssa ]
+ %epil.iter505 = phi i64 [ %epil.iter505.next, %for.body140.epil ], [ 0, %sw.epilog201.loopexit484.unr-lcssa ]
+ %indvars.iv.next415.epil = add nuw nsw i64 %indvars.iv414.epil, 1
+ %indvars416.epil = trunc i64 %indvars.iv.next415.epil to i32
+ %65 = trunc nuw nsw i64 %indvars.iv414.epil to i32
+ %add142.epil = mul i32 %indvars416.epil, %65
+ %add143.epil = add nsw i32 %add142.epil, 3
+ %arrayidx145.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv414.epil
+ store i32 %add143.epil, ptr %arrayidx145.epil, align 4, !tbaa !4
+ %epil.iter505.next = add i64 %epil.iter505, 1
+ %epil.iter505.cmp.not = icmp eq i64 %epil.iter505.next, %xtraiter504
+ br i1 %epil.iter505.cmp.not, label %sw.epilog201, label %for.body140.epil, !llvm.loop !29
+
+sw.epilog201.loopexit485.unr-lcssa: ; preds = %for.body156, %for.body156.preheader
+ %indvars.iv407.unr = phi i64 [ 0, %for.body156.preheader ], [ %indvars.iv.next408.3, %for.body156 ]
+ %lcmp.mod501.not = icmp eq i64 %xtraiter499, 0
+ br i1 %lcmp.mod501.not, label %sw.epilog201, label %for.body156.epil
+
+for.body156.epil: ; preds = %sw.epilog201.loopexit485.unr-lcssa, %for.body156.epil
+ %indvars.iv407.epil = phi i64 [ %indvars.iv.next408.epil, %for.body156.epil ], [ %indvars.iv407.unr, %sw.epilog201.loopexit485.unr-lcssa ]
+ %epil.iter500 = phi i64 [ %epil.iter500.next, %for.body156.epil ], [ 0, %sw.epilog201.loopexit485.unr-lcssa ]
+ %66 = trunc nuw nsw i64 %indvars.iv407.epil to i32
+ %mul158316.epil = mul i32 %66, %66
+ %67 = trunc i64 %indvars.iv407.epil to i32
+ %68 = add i32 %67, -1
+ %sub160.epil = mul i32 %mul158316.epil, %68
+ %arrayidx162.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv407.epil
+ store i32 %sub160.epil, ptr %arrayidx162.epil, align 4, !tbaa !4
+ %indvars.iv.next408.epil = add nuw nsw i64 %indvars.iv407.epil, 1
+ %epil.iter500.next = add i64 %epil.iter500, 1
+ %epil.iter500.cmp.not = icmp eq i64 %epil.iter500.next, %xtraiter499
+ br i1 %epil.iter500.cmp.not, label %sw.epilog201, label %for.body156.epil, !llvm.loop !30
+
+sw.epilog201.loopexit486.unr-lcssa: ; preds = %for.body173, %for.body173.preheader
+ %indvars.iv401.unr = phi i64 [ 0, %for.body173.preheader ], [ %indvars.iv.next402.3, %for.body173 ]
+ %lcmp.mod496.not = icmp eq i64 %xtraiter494, 0
+ br i1 %lcmp.mod496.not, label %sw.epilog201, label %for.body173.epil
+
+for.body173.epil: ; preds = %sw.epilog201.loopexit486.unr-lcssa, %for.body173.epil
+ %indvars.iv401.epil = phi i64 [ %indvars.iv.next402.epil, %for.body173.epil ], [ %indvars.iv401.unr, %sw.epilog201.loopexit486.unr-lcssa ]
+ %epil.iter495 = phi i64 [ %epil.iter495.next, %for.body173.epil ], [ 0, %sw.epilog201.loopexit486.unr-lcssa ]
+ %indvars.iv.next402.epil = add nuw nsw i64 %indvars.iv401.epil, 1
+ %indvars403.epil = trunc i64 %indvars.iv.next402.epil to i32
+ %69 = trunc nuw nsw i64 %indvars.iv401.epil to i32
+ %mul175312.epil = mul i32 %indvars403.epil, %69
+ %add177314.epil = add i32 %mul175312.epil, 3
+ %add179.epil = mul i32 %add177314.epil, %69
+ %arrayidx181.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv401.epil
+ store i32 %add179.epil, ptr %arrayidx181.epil, align 4, !tbaa !4
+ %epil.iter495.next = add i64 %epil.iter495, 1
+ %epil.iter495.cmp.not = icmp eq i64 %epil.iter495.next, %xtraiter494
+ br i1 %epil.iter495.cmp.not, label %sw.epilog201, label %for.body173.epil, !llvm.loop !31
+
+sw.epilog201.loopexit487.unr-lcssa: ; preds = %for.body192, %for.body192.preheader
+ %indvars.iv394.unr = phi i64 [ 0, %for.body192.preheader ], [ %indvars.iv.next395.3, %for.body192 ]
+ %lcmp.mod491.not = icmp eq i64 %xtraiter489, 0
+ br i1 %lcmp.mod491.not, label %sw.epilog201, label %for.body192.epil
+
+for.body192.epil: ; preds = %sw.epilog201.loopexit487.unr-lcssa, %for.body192.epil
+ %indvars.iv394.epil = phi i64 [ %indvars.iv.next395.epil, %for.body192.epil ], [ %indvars.iv394.unr, %sw.epilog201.loopexit487.unr-lcssa ]
+ %epil.iter490 = phi i64 [ %epil.iter490.next, %for.body192.epil ], [ 0, %sw.epilog201.loopexit487.unr-lcssa ]
+ %indvars398.epil = trunc i64 %indvars.iv394.epil to i32
+ %mul194310.epil = add nuw i32 %indvars398.epil, 3
+ %add195.epil = mul i32 %mul194310.epil, %indvars398.epil
+ %arrayidx197.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv394.epil
+ store i32 %add195.epil, ptr %arrayidx197.epil, align 4, !tbaa !4
+ %indvars.iv.next395.epil = add nuw nsw i64 %indvars.iv394.epil, 1
+ %epil.iter490.next = add i64 %epil.iter490, 1
+ %epil.iter490.cmp.not = icmp eq i64 %epil.iter490.next, %xtraiter489
+ br i1 %epil.iter490.cmp.not, label %sw.epilog201, label %for.body192.epil, !llvm.loop !32
+
+sw.epilog201: ; preds = %sw.epilog201.loopexit487.unr-lcssa, %for.body192.epil, %sw.epilog201.loopexit486.unr-lcssa, %for.body173.epil, %sw.epilog201.loopexit485.unr-lcssa, %for.body156.epil, %sw.epilog201.loopexit484.unr-lcssa, %for.body140.epil, %sw.epilog201.loopexit.unr-lcssa, %for.body120.epil, %sw.bb185, %sw.bb166, %sw.bb149, %sw.bb133, %sw.bb113, %for.cond.cleanup104
+ call void @func3()
+ unreachable
+
+if.else202: ; preds = %for.cond.cleanup
+ %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %70 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp206352 = icmp sgt i32 %70, 0
+ br i1 %cmp206352, label %for.body209, label %for.cond.cleanup208
+
+for.cond.cleanup208: ; preds = %for.body209, %if.else202
+ call void @func2()
+ unreachable
+
+for.body209: ; preds = %if.else202, %for.body209
+ %indvars.iv386 = phi i64 [ %indvars.iv.next387, %for.body209 ], [ 0, %if.else202 ]
+ %arrayidx211 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv386
+ %71 = load i32, ptr %arrayidx211, align 4, !tbaa !4
+ %call212 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %71)
+ %indvars.iv.next387 = add nuw nsw i64 %indvars.iv386, 1
+ %72 = load i32, ptr %len, align 4, !tbaa !4
+ %73 = sext i32 %72 to i64
+ %cmp206 = icmp slt i64 %indvars.iv.next387, %73
+ br i1 %cmp206, label %for.body209, label %for.cond.cleanup208, !llvm.loop !33
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+entry:
+; CHECK: larl %r0, .LBB3_13
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r11, 0(%r1)
+; CHECK: stg %r15, 24(%r1)
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.34)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.33)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+attributes #5 = { nounwind }
+attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = distinct !{!8, !9}
+!9 = !{!"llvm.loop.unroll.disable"}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
+!13 = distinct !{!13, !11}
+!14 = distinct !{!14, !11}
+!15 = distinct !{!15, !11}
+!16 = distinct !{!16, !11}
+!17 = distinct !{!17, !9}
+!18 = distinct !{!18, !9}
+!19 = distinct !{!19, !9}
+!20 = distinct !{!20, !9}
+!21 = distinct !{!21, !9}
+!22 = distinct !{!22, !11}
+!23 = distinct !{!23, !11}
+!24 = distinct !{!24, !11}
+!25 = distinct !{!25, !11}
+!26 = distinct !{!26, !11}
+!27 = distinct !{!27, !11}
+!28 = distinct !{!28, !9}
+!29 = distinct !{!29, !9}
+!30 = distinct !{!30, !9}
+!31 = distinct !{!31, !9}
+!32 = distinct !{!32, !9}
+!33 = distinct !{!33, !11}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04.ll
new file mode 100644
index 00000000000000..a75e383212f20b
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04.ll
@@ -0,0 +1,163 @@
+; This tests Frame Pointer.
+; This test case produces Wrong result.
+; FIXME: Correct Output is:
+;First __builtin_setjmp in func1
+;Second __builtin_setjmp in func1
+;Returned from func4
+;Dynamic var: 10
+;Returned from func3
+;Dynamic var: 20
+; TODO: -mbackchain test
+
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-04.c'
+source_filename = "builtin-setjmp-longjmp-alloca-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [17 x i8] c"Dynamic var: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: Dynamic var: 10
+; CHECK: Returned from func3
+; CHECK: Dynamic var: 10
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else6
+
+if.then: ; preds = %entry
+ %puts13 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp1 = icmp eq i32 %1, 0
+ br i1 %cmp1, label %if.then2, label %if.else
+
+if.then2: ; preds = %if.then
+ %puts15 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts14 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func3()
+ unreachable
+
+if.else6: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp.i = icmp eq i32 %1, 0
+ br i1 %cmp.i, label %if.then.i, label %if.else6.i
+
+if.then.i: ; preds = %if.then
+ %puts13.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp1.i = icmp eq i32 %2, 0
+ br i1 %cmp1.i, label %if.then2.i, label %if.else.i
+
+if.then2.i: ; preds = %if.then.i
+ %puts15.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else.i: ; preds = %if.then.i
+ %puts14.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %call5.i = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func3()
+ unreachable
+
+if.else6.i: ; preds = %if.then
+ %puts.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %call8.i = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func2()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll
new file mode 100644
index 00000000000000..0e81b71af79df2
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll
@@ -0,0 +1,332 @@
+; -mbackchain option
+; Test for Frame Pointer in first slot in jmp_buf.
+; Test assembly for nested setjmp for alloa.
+; This test case takes input from stdin for size of alloca
+; and produce the right result.
+
+; RUN: llc < %s | FileCheck %s
+
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-01.c'
+source_filename = "builtin-setjmp-longjmp-alloca-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
+ at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
+ at .str.8 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.13 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.15 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.17 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.18 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+ %len = alloca i32, align 4
+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
+ store i32 10, ptr %len, align 4, !tbaa !4
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
+ %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
+ %0 = load i32, ptr %len, align 4, !tbaa !4
+ %conv = sext i32 %0 to i64
+ %mul = shl nsw i64 %conv, 2
+ %1 = alloca i8, i64 %mul, align 8
+ %cmp82 = icmp sgt i32 %0, 0
+ br i1 %cmp82, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %wide.trip.count = zext nneg i32 %0 to i64
+ %xtraiter = and i64 %wide.trip.count, 3
+ %2 = icmp ult i32 %0, 4
+ br i1 %2, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
+
+for.body.preheader.new: ; preds = %for.body.preheader
+ %unroll_iter = and i64 %wide.trip.count, 2147483644
+ br label %for.body
+
+for.cond.cleanup.loopexit.unr-lcssa: ; preds = %for.body, %for.body.preheader
+ %indvars.iv.unr = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next.3, %for.body ]
+ %lcmp.mod.not = icmp eq i64 %xtraiter, 0
+ br i1 %lcmp.mod.not, label %for.cond.cleanup, label %for.body.epil
+
+for.body.epil: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil
+ %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %for.body.epil ], [ %indvars.iv.unr, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
+ %indvars.epil = trunc i64 %indvars.iv.next.epil to i32
+ %3 = trunc nuw nsw i64 %indvars.iv.epil to i32
+ %add.epil = mul i32 %indvars.epil, %3
+ %arrayidx.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.epil
+ store i32 %add.epil, ptr %arrayidx.epil, align 4, !tbaa !4
+ %epil.iter.next = add i64 %epil.iter, 1
+ %epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
+ br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
+
+for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
+; CHECK: larl %r1, buf1
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r11, 0(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r3, 16(%r1)
+; CHECK: stg %r3, 0(%r15)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: br %r2
+
+ %4 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp4 = icmp eq i32 %4, 0
+ br i1 %cmp4, label %if.then, label %if.else40
+
+for.body: ; preds = %for.body, %for.body.preheader.new
+ %indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
+ %niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
+ %indvars.iv.next = or disjoint i64 %indvars.iv, 1
+ %indvars = trunc i64 %indvars.iv.next to i32
+ %5 = trunc nuw nsw i64 %indvars.iv to i32
+ %add = mul i32 %indvars, %5
+ %arrayidx = getelementptr inbounds i32, ptr %1, i64 %indvars.iv
+ store i32 %add, ptr %arrayidx, align 8, !tbaa !4
+ %indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
+ %indvars.1 = trunc i64 %indvars.iv.next.1 to i32
+ %6 = trunc nuw nsw i64 %indvars.iv.next to i32
+ %add.1 = mul i32 %indvars.1, %6
+ %arrayidx.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next
+ store i32 %add.1, ptr %arrayidx.1, align 4, !tbaa !4
+ %indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
+ %indvars.2 = trunc i64 %indvars.iv.next.2 to i32
+ %7 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
+ %add.2 = mul i32 %indvars.2, %7
+ %arrayidx.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.1
+ store i32 %add.2, ptr %arrayidx.2, align 8, !tbaa !4
+ %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
+ %indvars.3 = trunc i64 %indvars.iv.next.3 to i32
+ %8 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
+ %add.3 = mul i32 %indvars.3, %8
+ %arrayidx.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.2
+ store i32 %add.3, ptr %arrayidx.3, align 4, !tbaa !4
+ %niter.next.3 = add i64 %niter, 4
+ %niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
+ br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
+
+if.then: ; preds = %for.cond.cleanup
+ %puts75 = call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %9 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp7 = icmp eq i32 %9, 0
+ br i1 %cmp7, label %if.then9, label %if.else
+
+if.then9: ; preds = %if.then
+ %puts80 = call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts76 = call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ %10 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp1486 = icmp sgt i32 %10, 0
+ br i1 %cmp1486, label %for.body17, label %for.cond.cleanup28
+
+for.cond25.preheader: ; preds = %for.body17
+ %cmp2688 = icmp sgt i32 %13, 0
+ br i1 %cmp2688, label %for.body29.preheader, label %for.cond.cleanup28
+
+for.body29.preheader: ; preds = %for.cond25.preheader
+ %wide.trip.count104 = zext nneg i32 %13 to i64
+ %xtraiter108 = and i64 %wide.trip.count104, 3
+ %11 = icmp ult i32 %13, 4
+ br i1 %11, label %for.cond.cleanup28.loopexit.unr-lcssa, label %for.body29.preheader.new
+
+for.body29.preheader.new: ; preds = %for.body29.preheader
+ %unroll_iter111 = and i64 %wide.trip.count104, 2147483644
+ br label %for.body29
+
+for.body17: ; preds = %if.else, %for.body17
+ %indvars.iv96 = phi i64 [ %indvars.iv.next97, %for.body17 ], [ 0, %if.else ]
+ %arrayidx19 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv96
+ %12 = load i32, ptr %arrayidx19, align 4, !tbaa !4
+ %call20 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %12)
+ %indvars.iv.next97 = add nuw nsw i64 %indvars.iv96, 1
+ %13 = load i32, ptr %len, align 4, !tbaa !4
+ %14 = sext i32 %13 to i64
+ %cmp14 = icmp slt i64 %indvars.iv.next97, %14
+ br i1 %cmp14, label %for.body17, label %for.cond25.preheader, !llvm.loop !12
+
+for.cond.cleanup28.loopexit.unr-lcssa: ; preds = %for.body29, %for.body29.preheader
+ %indvars.iv100.unr = phi i64 [ 0, %for.body29.preheader ], [ %indvars.iv.next101.3, %for.body29 ]
+ %lcmp.mod110.not = icmp eq i64 %xtraiter108, 0
+ br i1 %lcmp.mod110.not, label %for.cond.cleanup28, label %for.body29.epil
+
+for.body29.epil: ; preds = %for.cond.cleanup28.loopexit.unr-lcssa, %for.body29.epil
+ %indvars.iv100.epil = phi i64 [ %indvars.iv.next101.epil, %for.body29.epil ], [ %indvars.iv100.unr, %for.cond.cleanup28.loopexit.unr-lcssa ]
+ %epil.iter109 = phi i64 [ %epil.iter109.next, %for.body29.epil ], [ 0, %for.cond.cleanup28.loopexit.unr-lcssa ]
+ %indvars.iv.next101.epil = add nuw nsw i64 %indvars.iv100.epil, 1
+ %indvars102.epil = trunc i64 %indvars.iv.next101.epil to i32
+ %15 = trunc nuw nsw i64 %indvars.iv100.epil to i32
+ %mul3177.epil = mul i32 %indvars102.epil, %15
+ %add3379.epil = add nuw nsw i32 %mul3177.epil, 1
+ %add34.epil = mul i32 %add3379.epil, %15
+ %arrayidx36.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv100.epil
+ store i32 %add34.epil, ptr %arrayidx36.epil, align 4, !tbaa !4
+ %epil.iter109.next = add i64 %epil.iter109, 1
+ %epil.iter109.cmp.not = icmp eq i64 %epil.iter109.next, %xtraiter108
+ br i1 %epil.iter109.cmp.not, label %for.cond.cleanup28, label %for.body29.epil, !llvm.loop !13
+
+for.cond.cleanup28: ; preds = %for.cond.cleanup28.loopexit.unr-lcssa, %for.body29.epil, %if.else, %for.cond25.preheader
+ call void @func3()
+ unreachable
+
+for.body29: ; preds = %for.body29, %for.body29.preheader.new
+ %indvars.iv100 = phi i64 [ 0, %for.body29.preheader.new ], [ %indvars.iv.next101.3, %for.body29 ]
+ %niter112 = phi i64 [ 0, %for.body29.preheader.new ], [ %niter112.next.3, %for.body29 ]
+ %indvars.iv.next101 = or disjoint i64 %indvars.iv100, 1
+ %indvars102 = trunc i64 %indvars.iv.next101 to i32
+ %16 = trunc nuw nsw i64 %indvars.iv100 to i32
+ %mul3177 = mul i32 %indvars102, %16
+ %add3379 = or disjoint i32 %mul3177, 1
+ %add34 = mul i32 %add3379, %16
+ %arrayidx36 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv100
+ store i32 %add34, ptr %arrayidx36, align 8, !tbaa !4
+ %indvars.iv.next101.1 = or disjoint i64 %indvars.iv100, 2
+ %indvars102.1 = trunc i64 %indvars.iv.next101.1 to i32
+ %17 = trunc nuw nsw i64 %indvars.iv.next101 to i32
+ %mul3177.1 = mul i32 %indvars102.1, %17
+ %add3379.1 = or disjoint i32 %mul3177.1, 1
+ %add34.1 = mul i32 %add3379.1, %17
+ %arrayidx36.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101
+ store i32 %add34.1, ptr %arrayidx36.1, align 4, !tbaa !4
+ %indvars.iv.next101.2 = or disjoint i64 %indvars.iv100, 3
+ %indvars102.2 = trunc i64 %indvars.iv.next101.2 to i32
+ %18 = trunc nuw nsw i64 %indvars.iv.next101.1 to i32
+ %mul3177.2 = mul i32 %indvars102.2, %18
+ %add3379.2 = or disjoint i32 %mul3177.2, 1
+ %add34.2 = mul i32 %add3379.2, %18
+ %arrayidx36.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101.1
+ store i32 %add34.2, ptr %arrayidx36.2, align 8, !tbaa !4
+ %indvars.iv.next101.3 = add nuw nsw i64 %indvars.iv100, 4
+ %indvars102.3 = trunc i64 %indvars.iv.next101.3 to i32
+ %19 = trunc nuw nsw i64 %indvars.iv.next101.2 to i32
+ %mul3177.3 = mul i32 %indvars102.3, %19
+ %add3379.3 = or disjoint i32 %mul3177.3, 1
+ %add34.3 = mul i32 %add3379.3, %19
+ %arrayidx36.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101.2
+ store i32 %add34.3, ptr %arrayidx36.3, align 4, !tbaa !4
+ %niter112.next.3 = add i64 %niter112, 4
+ %niter112.ncmp.3 = icmp eq i64 %niter112.next.3, %unroll_iter111
+ br i1 %niter112.ncmp.3, label %for.cond.cleanup28.loopexit.unr-lcssa, label %for.body29, !llvm.loop !14
+
+if.else40: ; preds = %for.cond.cleanup
+ %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %20 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp4484 = icmp sgt i32 %20, 0
+ br i1 %cmp4484, label %for.body47, label %for.cond.cleanup46
+
+for.cond.cleanup46: ; preds = %for.body47, %if.else40
+ call void @func2()
+ unreachable
+
+for.body47: ; preds = %if.else40, %for.body47
+ %indvars.iv92 = phi i64 [ %indvars.iv.next93, %for.body47 ], [ 0, %if.else40 ]
+ %arrayidx49 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv92
+ %21 = load i32, ptr %arrayidx49, align 4, !tbaa !4
+ %call50 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %21)
+ %indvars.iv.next93 = add nuw nsw i64 %indvars.iv92, 1
+ %22 = load i32, ptr %len, align 4, !tbaa !4
+ %23 = sext i32 %22 to i64
+ %cmp44 = icmp slt i64 %indvars.iv.next93, %23
+ br i1 %cmp44, label %for.body47, label %for.cond.cleanup46, !llvm.loop !15
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+attributes #5 = { nounwind }
+attributes #6 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = distinct !{!8, !9}
+!9 = !{!"llvm.loop.unroll.disable"}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
+!13 = distinct !{!13, !9}
+!14 = distinct !{!14, !11}
+!15 = distinct !{!15, !11}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-03.ll
new file mode 100644
index 00000000000000..3d787de19e3737
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-03.ll
@@ -0,0 +1,1037 @@
+; -mbackchain option
+; Test for Frame Pointer in first slot in jmp_buf.
+; Test assembly for nested setjmp for alloa with switch statement.
+; This test case takes input from stdin for size of alloca
+; and produce the right result.
+; Frame Pointer in slot 1.
+; Return address in slot 2.
+; Backchain value in slot 3.
+; Stack Pointer in slot 4.
+
+; RUN: llc < %s | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-03.c'
+source_filename = "builtin-setjmp-longjmp-alloca-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
+ at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
+ at .str.13 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.17 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.18 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.20 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.21 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.27 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.28 = private unnamed_addr constant [8 x i8] c"case 4:\00", align 1
+ at str.29 = private unnamed_addr constant [8 x i8] c"case 3:\00", align 1
+ at str.30 = private unnamed_addr constant [8 x i8] c"case 2:\00", align 1
+ at str.31 = private unnamed_addr constant [8 x i8] c"case 1:\00", align 1
+ at str.32 = private unnamed_addr constant [8 x i8] c"case 0:\00", align 1
+ at str.33 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.34 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+ %len = alloca i32, align 4
+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
+ store i32 10, ptr %len, align 4, !tbaa !4
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
+ %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
+ %0 = load i32, ptr %len, align 4, !tbaa !4
+ %conv = sext i32 %0 to i64
+ %mul = shl nsw i64 %conv, 2
+ %1 = alloca i8, i64 %mul, align 8
+ %cmp350 = icmp sgt i32 %0, 0
+ br i1 %cmp350, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %wide.trip.count = zext nneg i32 %0 to i64
+ %xtraiter = and i64 %wide.trip.count, 3
+ %2 = icmp ult i32 %0, 4
+ br i1 %2, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
+
+for.body.preheader.new: ; preds = %for.body.preheader
+ %unroll_iter = and i64 %wide.trip.count, 2147483644
+ br label %for.body
+
+for.cond.cleanup.loopexit.unr-lcssa: ; preds = %for.body, %for.body.preheader
+ %indvars.iv.unr = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next.3, %for.body ]
+ %lcmp.mod.not = icmp eq i64 %xtraiter, 0
+ br i1 %lcmp.mod.not, label %for.cond.cleanup, label %for.body.epil
+
+for.body.epil: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil
+ %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %for.body.epil ], [ %indvars.iv.unr, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
+ %indvars.epil = trunc i64 %indvars.iv.next.epil to i32
+ %3 = trunc nuw nsw i64 %indvars.iv.epil to i32
+ %add.epil = mul i32 %indvars.epil, %3
+ %arrayidx.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.epil
+ store i32 %add.epil, ptr %arrayidx.epil, align 4, !tbaa !4
+ %epil.iter.next = add i64 %epil.iter, 1
+ %epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
+ br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
+
+for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
+ %4 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp4 = icmp eq i32 %4, 0
+ br i1 %cmp4, label %if.then, label %if.else202
+
+for.body: ; preds = %for.body, %for.body.preheader.new
+ %indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
+ %niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
+ %indvars.iv.next = or disjoint i64 %indvars.iv, 1
+ %indvars = trunc i64 %indvars.iv.next to i32
+ %5 = trunc nuw nsw i64 %indvars.iv to i32
+ %add = mul i32 %indvars, %5
+ %arrayidx = getelementptr inbounds i32, ptr %1, i64 %indvars.iv
+ store i32 %add, ptr %arrayidx, align 8, !tbaa !4
+ %indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
+ %indvars.1 = trunc i64 %indvars.iv.next.1 to i32
+ %6 = trunc nuw nsw i64 %indvars.iv.next to i32
+ %add.1 = mul i32 %indvars.1, %6
+ %arrayidx.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next
+ store i32 %add.1, ptr %arrayidx.1, align 4, !tbaa !4
+ %indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
+ %indvars.2 = trunc i64 %indvars.iv.next.2 to i32
+ %7 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
+ %add.2 = mul i32 %indvars.2, %7
+ %arrayidx.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.1
+ store i32 %add.2, ptr %arrayidx.2, align 8, !tbaa !4
+ %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
+ %indvars.3 = trunc i64 %indvars.iv.next.3 to i32
+ %8 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
+ %add.3 = mul i32 %indvars.3, %8
+ %arrayidx.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.2
+ store i32 %add.3, ptr %arrayidx.3, align 4, !tbaa !4
+ %niter.next.3 = add i64 %niter, 4
+ %niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
+ br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
+
+if.then: ; preds = %for.cond.cleanup
+ %puts307 = call i32 @puts(ptr nonnull dereferenceable(1) @str.20)
+ %9 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp7 = icmp eq i32 %9, 0
+ br i1 %cmp7, label %if.then9, label %if.else
+
+if.then9: ; preds = %if.then
+ %puts324 = call i32 @puts(ptr nonnull dereferenceable(1) @str.27)
+ %10 = load i32, ptr %len, align 4, !tbaa !4
+ %rem = srem i32 %10, 5
+ switch i32 %rem, label %sw.epilog [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb26
+ i32 2, label %sw.bb45
+ i32 3, label %sw.bb63
+ i32 4, label %sw.bb79
+ ]
+
+sw.bb: ; preds = %if.then9
+ %puts339 = call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
+ %11 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp14374 = icmp sgt i32 %11, 0
+ br i1 %cmp14374, label %for.body17.preheader, label %sw.epilog
+
+for.body17.preheader: ; preds = %sw.bb
+ %wide.trip.count460 = zext nneg i32 %11 to i64
+ %xtraiter534 = and i64 %wide.trip.count460, 3
+ %12 = icmp ult i32 %11, 4
+ br i1 %12, label %sw.epilog.loopexit.unr-lcssa, label %for.body17.preheader.new
+
+for.body17.preheader.new: ; preds = %for.body17.preheader
+ %unroll_iter537 = and i64 %wide.trip.count460, 2147483644
+ br label %for.body17
+
+for.body17: ; preds = %for.body17, %for.body17.preheader.new
+ %indvars.iv455 = phi i64 [ 0, %for.body17.preheader.new ], [ %indvars.iv.next456.3, %for.body17 ]
+ %niter538 = phi i64 [ 0, %for.body17.preheader.new ], [ %niter538.next.3, %for.body17 ]
+ %indvars459 = trunc i64 %indvars.iv455 to i32
+ %mul19340 = or disjoint i32 %indvars459, 3
+ %add20 = mul i32 %mul19340, %indvars459
+ %arrayidx22 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv455
+ store i32 %add20, ptr %arrayidx22, align 8, !tbaa !4
+ %indvars.iv.next456 = or disjoint i64 %indvars.iv455, 1
+ %indvars459.1 = trunc i64 %indvars.iv.next456 to i32
+ %mul19340.1 = add nuw i32 %indvars459.1, 3
+ %add20.1 = mul i32 %mul19340.1, %indvars459.1
+ %arrayidx22.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456
+ store i32 %add20.1, ptr %arrayidx22.1, align 4, !tbaa !4
+ %indvars.iv.next456.1 = or disjoint i64 %indvars.iv455, 2
+ %indvars459.2 = trunc i64 %indvars.iv.next456.1 to i32
+ %mul19340.2 = add nuw i32 %indvars459.2, 3
+ %add20.2 = mul i32 %mul19340.2, %indvars459.2
+ %arrayidx22.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456.1
+ store i32 %add20.2, ptr %arrayidx22.2, align 8, !tbaa !4
+ %indvars.iv.next456.2 = or disjoint i64 %indvars.iv455, 3
+ %indvars459.3 = trunc i64 %indvars.iv.next456.2 to i32
+ %mul19340.3 = add nuw i32 %indvars459.3, 3
+ %add20.3 = mul i32 %mul19340.3, %indvars459.3
+ %arrayidx22.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456.2
+ store i32 %add20.3, ptr %arrayidx22.3, align 4, !tbaa !4
+ %indvars.iv.next456.3 = add nuw nsw i64 %indvars.iv455, 4
+ %niter538.next.3 = add i64 %niter538, 4
+ %niter538.ncmp.3 = icmp eq i64 %niter538.next.3, %unroll_iter537
+ br i1 %niter538.ncmp.3, label %sw.epilog.loopexit.unr-lcssa, label %for.body17, !llvm.loop !12
+
+sw.bb26: ; preds = %if.then9
+ %puts335 = call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
+ %13 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp30372 = icmp sgt i32 %13, 0
+ br i1 %cmp30372, label %for.body33.preheader, label %sw.epilog
+
+for.body33.preheader: ; preds = %sw.bb26
+ %wide.trip.count453 = zext nneg i32 %13 to i64
+ %xtraiter529 = and i64 %wide.trip.count453, 3
+ %14 = icmp ult i32 %13, 4
+ br i1 %14, label %sw.epilog.loopexit480.unr-lcssa, label %for.body33.preheader.new
+
+for.body33.preheader.new: ; preds = %for.body33.preheader
+ %unroll_iter532 = and i64 %wide.trip.count453, 2147483644
+ br label %for.body33
+
+for.body33: ; preds = %for.body33, %for.body33.preheader.new
+ %indvars.iv449 = phi i64 [ 0, %for.body33.preheader.new ], [ %indvars.iv.next450.3, %for.body33 ]
+ %niter533 = phi i64 [ 0, %for.body33.preheader.new ], [ %niter533.next.3, %for.body33 ]
+ %indvars.iv.next450 = or disjoint i64 %indvars.iv449, 1
+ %indvars451 = trunc i64 %indvars.iv.next450 to i32
+ %15 = trunc nuw nsw i64 %indvars.iv449 to i32
+ %mul35336 = mul i32 %indvars451, %15
+ %add37338 = or disjoint i32 %mul35336, 3
+ %add39 = mul i32 %add37338, %15
+ %arrayidx41 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv449
+ store i32 %add39, ptr %arrayidx41, align 8, !tbaa !4
+ %indvars.iv.next450.1 = or disjoint i64 %indvars.iv449, 2
+ %indvars451.1 = trunc i64 %indvars.iv.next450.1 to i32
+ %16 = trunc nuw nsw i64 %indvars.iv.next450 to i32
+ %mul35336.1 = mul i32 %indvars451.1, %16
+ %add37338.1 = add i32 %mul35336.1, 3
+ %add39.1 = mul i32 %add37338.1, %16
+ %arrayidx41.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450
+ store i32 %add39.1, ptr %arrayidx41.1, align 4, !tbaa !4
+ %indvars.iv.next450.2 = or disjoint i64 %indvars.iv449, 3
+ %indvars451.2 = trunc i64 %indvars.iv.next450.2 to i32
+ %17 = trunc nuw nsw i64 %indvars.iv.next450.1 to i32
+ %mul35336.2 = mul i32 %indvars451.2, %17
+ %add37338.2 = add i32 %mul35336.2, 3
+ %add39.2 = mul i32 %add37338.2, %17
+ %arrayidx41.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450.1
+ store i32 %add39.2, ptr %arrayidx41.2, align 8, !tbaa !4
+ %indvars.iv.next450.3 = add nuw nsw i64 %indvars.iv449, 4
+ %indvars451.3 = trunc i64 %indvars.iv.next450.3 to i32
+ %18 = trunc nuw nsw i64 %indvars.iv.next450.2 to i32
+ %mul35336.3 = mul i32 %indvars451.3, %18
+ %add37338.3 = or disjoint i32 %mul35336.3, 3
+ %add39.3 = mul i32 %add37338.3, %18
+ %arrayidx41.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450.2
+ store i32 %add39.3, ptr %arrayidx41.3, align 4, !tbaa !4
+ %niter533.next.3 = add i64 %niter533, 4
+ %niter533.ncmp.3 = icmp eq i64 %niter533.next.3, %unroll_iter532
+ br i1 %niter533.ncmp.3, label %sw.epilog.loopexit480.unr-lcssa, label %for.body33, !llvm.loop !13
+
+sw.bb45: ; preds = %if.then9
+ %puts331 = call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
+ %19 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp49370 = icmp sgt i32 %19, 0
+ br i1 %cmp49370, label %for.body52.preheader, label %sw.epilog
+
+for.body52.preheader: ; preds = %sw.bb45
+ %wide.trip.count447 = zext nneg i32 %19 to i64
+ %xtraiter524 = and i64 %wide.trip.count447, 3
+ %20 = icmp ult i32 %19, 4
+ br i1 %20, label %sw.epilog.loopexit481.unr-lcssa, label %for.body52.preheader.new
+
+for.body52.preheader.new: ; preds = %for.body52.preheader
+ %unroll_iter527 = and i64 %wide.trip.count447, 2147483644
+ br label %for.body52
+
+for.body52: ; preds = %for.body52, %for.body52.preheader.new
+ %indvars.iv442 = phi i64 [ 0, %for.body52.preheader.new ], [ %indvars.iv.next443.3, %for.body52 ]
+ %niter528 = phi i64 [ 0, %for.body52.preheader.new ], [ %niter528.next.3, %for.body52 ]
+ %indvars446 = trunc i64 %indvars.iv442 to i32
+ %i47.0333 = add nsw i32 %indvars446, -1
+ %mul54332 = mul i32 %i47.0333, %indvars446
+ %sub334 = or disjoint i32 %mul54332, 3
+ %add57 = mul i32 %sub334, %indvars446
+ %arrayidx59 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv442
+ store i32 %add57, ptr %arrayidx59, align 8, !tbaa !4
+ %indvars.iv.next443 = or disjoint i64 %indvars.iv442, 1
+ %indvars446.1 = trunc i64 %indvars.iv.next443 to i32
+ %i47.0333.1 = add nsw i32 %indvars446.1, -1
+ %mul54332.1 = mul i32 %i47.0333.1, %indvars446.1
+ %sub334.1 = or disjoint i32 %mul54332.1, 3
+ %add57.1 = mul i32 %sub334.1, %indvars446.1
+ %arrayidx59.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443
+ store i32 %add57.1, ptr %arrayidx59.1, align 4, !tbaa !4
+ %indvars.iv.next443.1 = or disjoint i64 %indvars.iv442, 2
+ %indvars446.2 = trunc i64 %indvars.iv.next443.1 to i32
+ %i47.0333.2 = add nsw i32 %indvars446.2, -1
+ %mul54332.2 = mul i32 %i47.0333.2, %indvars446.2
+ %sub334.2 = add i32 %mul54332.2, 3
+ %add57.2 = mul i32 %sub334.2, %indvars446.2
+ %arrayidx59.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443.1
+ store i32 %add57.2, ptr %arrayidx59.2, align 8, !tbaa !4
+ %indvars.iv.next443.2 = or disjoint i64 %indvars.iv442, 3
+ %indvars446.3 = trunc i64 %indvars.iv.next443.2 to i32
+ %i47.0333.3 = add nsw i32 %indvars446.3, -1
+ %mul54332.3 = mul i32 %i47.0333.3, %indvars446.3
+ %sub334.3 = add i32 %mul54332.3, 3
+ %add57.3 = mul i32 %sub334.3, %indvars446.3
+ %arrayidx59.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443.2
+ store i32 %add57.3, ptr %arrayidx59.3, align 4, !tbaa !4
+ %indvars.iv.next443.3 = add nuw nsw i64 %indvars.iv442, 4
+ %niter528.next.3 = add i64 %niter528, 4
+ %niter528.ncmp.3 = icmp eq i64 %niter528.next.3, %unroll_iter527
+ br i1 %niter528.ncmp.3, label %sw.epilog.loopexit481.unr-lcssa, label %for.body52, !llvm.loop !14
+
+sw.bb63: ; preds = %if.then9
+ %puts329 = call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
+ %21 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp67368 = icmp sgt i32 %21, 0
+ br i1 %cmp67368, label %for.body70.preheader, label %sw.epilog
+
+for.body70.preheader: ; preds = %sw.bb63
+ %wide.trip.count440 = zext nneg i32 %21 to i64
+ %xtraiter519 = and i64 %wide.trip.count440, 3
+ %22 = icmp ult i32 %21, 4
+ br i1 %22, label %sw.epilog.loopexit482.unr-lcssa, label %for.body70.preheader.new
+
+for.body70.preheader.new: ; preds = %for.body70.preheader
+ %unroll_iter522 = and i64 %wide.trip.count440, 2147483644
+ br label %for.body70
+
+for.body70: ; preds = %for.body70, %for.body70.preheader.new
+ %indvars.iv436 = phi i64 [ 0, %for.body70.preheader.new ], [ %indvars.iv.next437.3, %for.body70 ]
+ %niter523 = phi i64 [ 0, %for.body70.preheader.new ], [ %niter523.next.3, %for.body70 ]
+ %indvars.iv.next437 = or disjoint i64 %indvars.iv436, 1
+ %indvars438 = trunc i64 %indvars.iv.next437 to i32
+ %23 = trunc nuw nsw i64 %indvars.iv436 to i32
+ %add72 = mul i32 %indvars438, %23
+ %add73 = or disjoint i32 %add72, 3
+ %arrayidx75 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv436
+ store i32 %add73, ptr %arrayidx75, align 8, !tbaa !4
+ %indvars.iv.next437.1 = or disjoint i64 %indvars.iv436, 2
+ %indvars438.1 = trunc i64 %indvars.iv.next437.1 to i32
+ %24 = trunc nuw nsw i64 %indvars.iv.next437 to i32
+ %add72.1 = mul i32 %indvars438.1, %24
+ %add73.1 = add nsw i32 %add72.1, 3
+ %arrayidx75.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437
+ store i32 %add73.1, ptr %arrayidx75.1, align 4, !tbaa !4
+ %indvars.iv.next437.2 = or disjoint i64 %indvars.iv436, 3
+ %indvars438.2 = trunc i64 %indvars.iv.next437.2 to i32
+ %25 = trunc nuw nsw i64 %indvars.iv.next437.1 to i32
+ %add72.2 = mul i32 %indvars438.2, %25
+ %add73.2 = add nsw i32 %add72.2, 3
+ %arrayidx75.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437.1
+ store i32 %add73.2, ptr %arrayidx75.2, align 8, !tbaa !4
+ %indvars.iv.next437.3 = add nuw nsw i64 %indvars.iv436, 4
+ %indvars438.3 = trunc i64 %indvars.iv.next437.3 to i32
+ %26 = trunc nuw nsw i64 %indvars.iv.next437.2 to i32
+ %add72.3 = mul i32 %indvars438.3, %26
+ %add73.3 = or disjoint i32 %add72.3, 3
+ %arrayidx75.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437.2
+ store i32 %add73.3, ptr %arrayidx75.3, align 4, !tbaa !4
+ %niter523.next.3 = add i64 %niter523, 4
+ %niter523.ncmp.3 = icmp eq i64 %niter523.next.3, %unroll_iter522
+ br i1 %niter523.ncmp.3, label %sw.epilog.loopexit482.unr-lcssa, label %for.body70, !llvm.loop !15
+
+sw.bb79: ; preds = %if.then9
+ %puts325 = call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
+ %27 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp83366 = icmp sgt i32 %27, 0
+ br i1 %cmp83366, label %for.body86.preheader, label %sw.epilog
+
+for.body86.preheader: ; preds = %sw.bb79
+ %wide.trip.count434 = zext nneg i32 %27 to i64
+ %xtraiter514 = and i64 %wide.trip.count434, 3
+ %28 = icmp ult i32 %27, 4
+ br i1 %28, label %sw.epilog.loopexit483.unr-lcssa, label %for.body86.preheader.new
+
+for.body86.preheader.new: ; preds = %for.body86.preheader
+ %unroll_iter517 = and i64 %wide.trip.count434, 2147483644
+ br label %for.body86
+
+for.body86: ; preds = %for.body86, %for.body86.preheader.new
+ %indvars.iv428 = phi i64 [ 0, %for.body86.preheader.new ], [ %indvars.iv.next429.3, %for.body86 ]
+ %niter518 = phi i64 [ 0, %for.body86.preheader.new ], [ %niter518.next.3, %for.body86 ]
+ %indvars433 = trunc i64 %indvars.iv428 to i32
+ %mul87 = mul nuw nsw i32 %indvars433, %indvars433
+ %mul88327 = or disjoint i32 %mul87, 1
+ %mul89326 = mul i32 %mul88327, %indvars433
+ %add91328 = or disjoint i32 %mul89326, 3
+ %add93 = mul i32 %add91328, %indvars433
+ %arrayidx95 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv428
+ store i32 %add93, ptr %arrayidx95, align 8, !tbaa !4
+ %indvars.iv.next429 = or disjoint i64 %indvars.iv428, 1
+ %indvars433.1 = trunc i64 %indvars.iv.next429 to i32
+ %mul87.1 = mul nuw nsw i32 %indvars433.1, %indvars433.1
+ %mul88327.1 = add nuw nsw i32 %mul87.1, 1
+ %mul89326.1 = mul i32 %mul88327.1, %indvars433.1
+ %add91328.1 = add i32 %mul89326.1, 3
+ %add93.1 = mul i32 %add91328.1, %indvars433.1
+ %arrayidx95.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429
+ store i32 %add93.1, ptr %arrayidx95.1, align 4, !tbaa !4
+ %indvars.iv.next429.1 = or disjoint i64 %indvars.iv428, 2
+ %indvars433.2 = trunc i64 %indvars.iv.next429.1 to i32
+ %mul87.2 = mul nuw nsw i32 %indvars433.2, %indvars433.2
+ %mul88327.2 = or disjoint i32 %mul87.2, 1
+ %mul89326.2 = mul i32 %mul88327.2, %indvars433.2
+ %add91328.2 = add i32 %mul89326.2, 3
+ %add93.2 = mul i32 %add91328.2, %indvars433.2
+ %arrayidx95.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429.1
+ store i32 %add93.2, ptr %arrayidx95.2, align 8, !tbaa !4
+ %indvars.iv.next429.2 = or disjoint i64 %indvars.iv428, 3
+ %indvars433.3 = trunc i64 %indvars.iv.next429.2 to i32
+ %mul87.3 = mul nuw nsw i32 %indvars433.3, %indvars433.3
+ %mul88327.3 = add nuw nsw i32 %mul87.3, 1
+ %mul89326.3 = mul i32 %mul88327.3, %indvars433.3
+ %add91328.3 = add i32 %mul89326.3, 3
+ %add93.3 = mul i32 %add91328.3, %indvars433.3
+ %arrayidx95.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429.2
+ store i32 %add93.3, ptr %arrayidx95.3, align 4, !tbaa !4
+ %indvars.iv.next429.3 = add nuw nsw i64 %indvars.iv428, 4
+ %niter518.next.3 = add i64 %niter518, 4
+ %niter518.ncmp.3 = icmp eq i64 %niter518.next.3, %unroll_iter517
+ br i1 %niter518.ncmp.3, label %sw.epilog.loopexit483.unr-lcssa, label %for.body86, !llvm.loop !16
+
+sw.epilog.loopexit.unr-lcssa: ; preds = %for.body17, %for.body17.preheader
+ %indvars.iv455.unr = phi i64 [ 0, %for.body17.preheader ], [ %indvars.iv.next456.3, %for.body17 ]
+ %lcmp.mod536.not = icmp eq i64 %xtraiter534, 0
+ br i1 %lcmp.mod536.not, label %sw.epilog, label %for.body17.epil
+
+for.body17.epil: ; preds = %sw.epilog.loopexit.unr-lcssa, %for.body17.epil
+ %indvars.iv455.epil = phi i64 [ %indvars.iv.next456.epil, %for.body17.epil ], [ %indvars.iv455.unr, %sw.epilog.loopexit.unr-lcssa ]
+ %epil.iter535 = phi i64 [ %epil.iter535.next, %for.body17.epil ], [ 0, %sw.epilog.loopexit.unr-lcssa ]
+ %indvars459.epil = trunc i64 %indvars.iv455.epil to i32
+ %mul19340.epil = add nuw i32 %indvars459.epil, 3
+ %add20.epil = mul i32 %mul19340.epil, %indvars459.epil
+ %arrayidx22.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv455.epil
+ store i32 %add20.epil, ptr %arrayidx22.epil, align 4, !tbaa !4
+ %indvars.iv.next456.epil = add nuw nsw i64 %indvars.iv455.epil, 1
+ %epil.iter535.next = add i64 %epil.iter535, 1
+ %epil.iter535.cmp.not = icmp eq i64 %epil.iter535.next, %xtraiter534
+ br i1 %epil.iter535.cmp.not, label %sw.epilog, label %for.body17.epil, !llvm.loop !17
+
+sw.epilog.loopexit480.unr-lcssa: ; preds = %for.body33, %for.body33.preheader
+ %indvars.iv449.unr = phi i64 [ 0, %for.body33.preheader ], [ %indvars.iv.next450.3, %for.body33 ]
+ %lcmp.mod531.not = icmp eq i64 %xtraiter529, 0
+ br i1 %lcmp.mod531.not, label %sw.epilog, label %for.body33.epil
+
+for.body33.epil: ; preds = %sw.epilog.loopexit480.unr-lcssa, %for.body33.epil
+ %indvars.iv449.epil = phi i64 [ %indvars.iv.next450.epil, %for.body33.epil ], [ %indvars.iv449.unr, %sw.epilog.loopexit480.unr-lcssa ]
+ %epil.iter530 = phi i64 [ %epil.iter530.next, %for.body33.epil ], [ 0, %sw.epilog.loopexit480.unr-lcssa ]
+ %indvars.iv.next450.epil = add nuw nsw i64 %indvars.iv449.epil, 1
+ %indvars451.epil = trunc i64 %indvars.iv.next450.epil to i32
+ %29 = trunc nuw nsw i64 %indvars.iv449.epil to i32
+ %mul35336.epil = mul i32 %indvars451.epil, %29
+ %add37338.epil = add i32 %mul35336.epil, 3
+ %add39.epil = mul i32 %add37338.epil, %29
+ %arrayidx41.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv449.epil
+ store i32 %add39.epil, ptr %arrayidx41.epil, align 4, !tbaa !4
+ %epil.iter530.next = add i64 %epil.iter530, 1
+ %epil.iter530.cmp.not = icmp eq i64 %epil.iter530.next, %xtraiter529
+ br i1 %epil.iter530.cmp.not, label %sw.epilog, label %for.body33.epil, !llvm.loop !18
+
+sw.epilog.loopexit481.unr-lcssa: ; preds = %for.body52, %for.body52.preheader
+ %indvars.iv442.unr = phi i64 [ 0, %for.body52.preheader ], [ %indvars.iv.next443.3, %for.body52 ]
+ %lcmp.mod526.not = icmp eq i64 %xtraiter524, 0
+ br i1 %lcmp.mod526.not, label %sw.epilog, label %for.body52.epil
+
+for.body52.epil: ; preds = %sw.epilog.loopexit481.unr-lcssa, %for.body52.epil
+ %indvars.iv442.epil = phi i64 [ %indvars.iv.next443.epil, %for.body52.epil ], [ %indvars.iv442.unr, %sw.epilog.loopexit481.unr-lcssa ]
+ %epil.iter525 = phi i64 [ %epil.iter525.next, %for.body52.epil ], [ 0, %sw.epilog.loopexit481.unr-lcssa ]
+ %indvars446.epil = trunc i64 %indvars.iv442.epil to i32
+ %i47.0333.epil = add nsw i32 %indvars446.epil, -1
+ %mul54332.epil = mul i32 %i47.0333.epil, %indvars446.epil
+ %sub334.epil = add i32 %mul54332.epil, 3
+ %add57.epil = mul i32 %sub334.epil, %indvars446.epil
+ %arrayidx59.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv442.epil
+ store i32 %add57.epil, ptr %arrayidx59.epil, align 4, !tbaa !4
+ %indvars.iv.next443.epil = add nuw nsw i64 %indvars.iv442.epil, 1
+ %epil.iter525.next = add i64 %epil.iter525, 1
+ %epil.iter525.cmp.not = icmp eq i64 %epil.iter525.next, %xtraiter524
+ br i1 %epil.iter525.cmp.not, label %sw.epilog, label %for.body52.epil, !llvm.loop !19
+
+sw.epilog.loopexit482.unr-lcssa: ; preds = %for.body70, %for.body70.preheader
+ %indvars.iv436.unr = phi i64 [ 0, %for.body70.preheader ], [ %indvars.iv.next437.3, %for.body70 ]
+ %lcmp.mod521.not = icmp eq i64 %xtraiter519, 0
+ br i1 %lcmp.mod521.not, label %sw.epilog, label %for.body70.epil
+
+for.body70.epil: ; preds = %sw.epilog.loopexit482.unr-lcssa, %for.body70.epil
+ %indvars.iv436.epil = phi i64 [ %indvars.iv.next437.epil, %for.body70.epil ], [ %indvars.iv436.unr, %sw.epilog.loopexit482.unr-lcssa ]
+ %epil.iter520 = phi i64 [ %epil.iter520.next, %for.body70.epil ], [ 0, %sw.epilog.loopexit482.unr-lcssa ]
+ %indvars.iv.next437.epil = add nuw nsw i64 %indvars.iv436.epil, 1
+ %indvars438.epil = trunc i64 %indvars.iv.next437.epil to i32
+ %30 = trunc nuw nsw i64 %indvars.iv436.epil to i32
+ %add72.epil = mul i32 %indvars438.epil, %30
+ %add73.epil = add nsw i32 %add72.epil, 3
+ %arrayidx75.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv436.epil
+ store i32 %add73.epil, ptr %arrayidx75.epil, align 4, !tbaa !4
+ %epil.iter520.next = add i64 %epil.iter520, 1
+ %epil.iter520.cmp.not = icmp eq i64 %epil.iter520.next, %xtraiter519
+ br i1 %epil.iter520.cmp.not, label %sw.epilog, label %for.body70.epil, !llvm.loop !20
+
+sw.epilog.loopexit483.unr-lcssa: ; preds = %for.body86, %for.body86.preheader
+ %indvars.iv428.unr = phi i64 [ 0, %for.body86.preheader ], [ %indvars.iv.next429.3, %for.body86 ]
+ %lcmp.mod516.not = icmp eq i64 %xtraiter514, 0
+ br i1 %lcmp.mod516.not, label %sw.epilog, label %for.body86.epil
+
+for.body86.epil: ; preds = %sw.epilog.loopexit483.unr-lcssa, %for.body86.epil
+ %indvars.iv428.epil = phi i64 [ %indvars.iv.next429.epil, %for.body86.epil ], [ %indvars.iv428.unr, %sw.epilog.loopexit483.unr-lcssa ]
+ %epil.iter515 = phi i64 [ %epil.iter515.next, %for.body86.epil ], [ 0, %sw.epilog.loopexit483.unr-lcssa ]
+ %indvars433.epil = trunc i64 %indvars.iv428.epil to i32
+ %mul87.epil = mul nuw nsw i32 %indvars433.epil, %indvars433.epil
+ %mul88327.epil = add nuw i32 %mul87.epil, 1
+ %mul89326.epil = mul i32 %mul88327.epil, %indvars433.epil
+ %add91328.epil = add i32 %mul89326.epil, 3
+ %add93.epil = mul i32 %add91328.epil, %indvars433.epil
+ %arrayidx95.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv428.epil
+ store i32 %add93.epil, ptr %arrayidx95.epil, align 4, !tbaa !4
+ %indvars.iv.next429.epil = add nuw nsw i64 %indvars.iv428.epil, 1
+ %epil.iter515.next = add i64 %epil.iter515, 1
+ %epil.iter515.cmp.not = icmp eq i64 %epil.iter515.next, %xtraiter514
+ br i1 %epil.iter515.cmp.not, label %sw.epilog, label %for.body86.epil, !llvm.loop !21
+
+sw.epilog: ; preds = %sw.epilog.loopexit483.unr-lcssa, %for.body86.epil, %sw.epilog.loopexit482.unr-lcssa, %for.body70.epil, %sw.epilog.loopexit481.unr-lcssa, %for.body52.epil, %sw.epilog.loopexit480.unr-lcssa, %for.body33.epil, %sw.epilog.loopexit.unr-lcssa, %for.body17.epil, %sw.bb79, %sw.bb63, %sw.bb45, %sw.bb26, %sw.bb, %if.then9
+ call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts308 = call i32 @puts(ptr nonnull dereferenceable(1) @str.21)
+ %31 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp102354 = icmp sgt i32 %31, 0
+ br i1 %cmp102354, label %for.body105, label %for.cond.cleanup104
+
+for.cond.cleanup104: ; preds = %for.body105, %if.else
+ %.lcssa = phi i32 [ %31, %if.else ], [ %33, %for.body105 ]
+ %rem112 = srem i32 %.lcssa, 5
+ switch i32 %rem112, label %sw.epilog201 [
+ i32 0, label %sw.bb113
+ i32 1, label %sw.bb133
+ i32 2, label %sw.bb149
+ i32 3, label %sw.bb166
+ i32 4, label %sw.bb185
+ ]
+
+for.body105: ; preds = %if.else, %for.body105
+ %indvars.iv390 = phi i64 [ %indvars.iv.next391, %for.body105 ], [ 0, %if.else ]
+ %arrayidx107 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv390
+ %32 = load i32, ptr %arrayidx107, align 4, !tbaa !4
+ %call108 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %32)
+ %indvars.iv.next391 = add nuw nsw i64 %indvars.iv390, 1
+ %33 = load i32, ptr %len, align 4, !tbaa !4
+ %34 = sext i32 %33 to i64
+ %cmp102 = icmp slt i64 %indvars.iv.next391, %34
+ br i1 %cmp102, label %for.body105, label %for.cond.cleanup104, !llvm.loop !22
+
+sw.bb113: ; preds = %for.cond.cleanup104
+ %puts320 = call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
+ %35 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp117364 = icmp sgt i32 %35, 0
+ br i1 %cmp117364, label %for.body120.preheader, label %sw.epilog201
+
+for.body120.preheader: ; preds = %sw.bb113
+ %wide.trip.count426 = zext nneg i32 %35 to i64
+ %xtraiter509 = and i64 %wide.trip.count426, 3
+ %36 = icmp ult i32 %35, 4
+ br i1 %36, label %sw.epilog201.loopexit.unr-lcssa, label %for.body120.preheader.new
+
+for.body120.preheader.new: ; preds = %for.body120.preheader
+ %unroll_iter512 = and i64 %wide.trip.count426, 2147483644
+ br label %for.body120
+
+for.body120: ; preds = %for.body120, %for.body120.preheader.new
+ %indvars.iv420 = phi i64 [ 0, %for.body120.preheader.new ], [ %indvars.iv.next421.3, %for.body120 ]
+ %niter513 = phi i64 [ 0, %for.body120.preheader.new ], [ %niter513.next.3, %for.body120 ]
+ %indvars425 = trunc i64 %indvars.iv420 to i32
+ %mul121 = mul nuw nsw i32 %indvars425, %indvars425
+ %mul122322 = or disjoint i32 %mul121, 1
+ %mul123321 = mul i32 %mul122322, %indvars425
+ %add125323 = or disjoint i32 %mul123321, 3
+ %add127 = mul i32 %add125323, %indvars425
+ %arrayidx129 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv420
+ store i32 %add127, ptr %arrayidx129, align 8, !tbaa !4
+ %indvars.iv.next421 = or disjoint i64 %indvars.iv420, 1
+ %indvars425.1 = trunc i64 %indvars.iv.next421 to i32
+ %mul121.1 = mul nuw nsw i32 %indvars425.1, %indvars425.1
+ %mul122322.1 = add nuw nsw i32 %mul121.1, 1
+ %mul123321.1 = mul i32 %mul122322.1, %indvars425.1
+ %add125323.1 = add i32 %mul123321.1, 3
+ %add127.1 = mul i32 %add125323.1, %indvars425.1
+ %arrayidx129.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421
+ store i32 %add127.1, ptr %arrayidx129.1, align 4, !tbaa !4
+ %indvars.iv.next421.1 = or disjoint i64 %indvars.iv420, 2
+ %indvars425.2 = trunc i64 %indvars.iv.next421.1 to i32
+ %mul121.2 = mul nuw nsw i32 %indvars425.2, %indvars425.2
+ %mul122322.2 = or disjoint i32 %mul121.2, 1
+ %mul123321.2 = mul i32 %mul122322.2, %indvars425.2
+ %add125323.2 = add i32 %mul123321.2, 3
+ %add127.2 = mul i32 %add125323.2, %indvars425.2
+ %arrayidx129.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421.1
+ store i32 %add127.2, ptr %arrayidx129.2, align 8, !tbaa !4
+ %indvars.iv.next421.2 = or disjoint i64 %indvars.iv420, 3
+ %indvars425.3 = trunc i64 %indvars.iv.next421.2 to i32
+ %mul121.3 = mul nuw nsw i32 %indvars425.3, %indvars425.3
+ %mul122322.3 = add nuw nsw i32 %mul121.3, 1
+ %mul123321.3 = mul i32 %mul122322.3, %indvars425.3
+ %add125323.3 = add i32 %mul123321.3, 3
+ %add127.3 = mul i32 %add125323.3, %indvars425.3
+ %arrayidx129.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421.2
+ store i32 %add127.3, ptr %arrayidx129.3, align 4, !tbaa !4
+ %indvars.iv.next421.3 = add nuw nsw i64 %indvars.iv420, 4
+ %niter513.next.3 = add i64 %niter513, 4
+ %niter513.ncmp.3 = icmp eq i64 %niter513.next.3, %unroll_iter512
+ br i1 %niter513.ncmp.3, label %sw.epilog201.loopexit.unr-lcssa, label %for.body120, !llvm.loop !23
+
+sw.bb133: ; preds = %for.cond.cleanup104
+ %puts318 = call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
+ %37 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp137362 = icmp sgt i32 %37, 0
+ br i1 %cmp137362, label %for.body140.preheader, label %sw.epilog201
+
+for.body140.preheader: ; preds = %sw.bb133
+ %wide.trip.count418 = zext nneg i32 %37 to i64
+ %xtraiter504 = and i64 %wide.trip.count418, 3
+ %38 = icmp ult i32 %37, 4
+ br i1 %38, label %sw.epilog201.loopexit484.unr-lcssa, label %for.body140.preheader.new
+
+for.body140.preheader.new: ; preds = %for.body140.preheader
+ %unroll_iter507 = and i64 %wide.trip.count418, 2147483644
+ br label %for.body140
+
+for.body140: ; preds = %for.body140, %for.body140.preheader.new
+ %indvars.iv414 = phi i64 [ 0, %for.body140.preheader.new ], [ %indvars.iv.next415.3, %for.body140 ]
+ %niter508 = phi i64 [ 0, %for.body140.preheader.new ], [ %niter508.next.3, %for.body140 ]
+ %indvars.iv.next415 = or disjoint i64 %indvars.iv414, 1
+ %indvars416 = trunc i64 %indvars.iv.next415 to i32
+ %39 = trunc nuw nsw i64 %indvars.iv414 to i32
+ %add142 = mul i32 %indvars416, %39
+ %add143 = or disjoint i32 %add142, 3
+ %arrayidx145 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv414
+ store i32 %add143, ptr %arrayidx145, align 8, !tbaa !4
+ %indvars.iv.next415.1 = or disjoint i64 %indvars.iv414, 2
+ %indvars416.1 = trunc i64 %indvars.iv.next415.1 to i32
+ %40 = trunc nuw nsw i64 %indvars.iv.next415 to i32
+ %add142.1 = mul i32 %indvars416.1, %40
+ %add143.1 = add nsw i32 %add142.1, 3
+ %arrayidx145.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415
+ store i32 %add143.1, ptr %arrayidx145.1, align 4, !tbaa !4
+ %indvars.iv.next415.2 = or disjoint i64 %indvars.iv414, 3
+ %indvars416.2 = trunc i64 %indvars.iv.next415.2 to i32
+ %41 = trunc nuw nsw i64 %indvars.iv.next415.1 to i32
+ %add142.2 = mul i32 %indvars416.2, %41
+ %add143.2 = add nsw i32 %add142.2, 3
+ %arrayidx145.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415.1
+ store i32 %add143.2, ptr %arrayidx145.2, align 8, !tbaa !4
+ %indvars.iv.next415.3 = add nuw nsw i64 %indvars.iv414, 4
+ %indvars416.3 = trunc i64 %indvars.iv.next415.3 to i32
+ %42 = trunc nuw nsw i64 %indvars.iv.next415.2 to i32
+ %add142.3 = mul i32 %indvars416.3, %42
+ %add143.3 = or disjoint i32 %add142.3, 3
+ %arrayidx145.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415.2
+ store i32 %add143.3, ptr %arrayidx145.3, align 4, !tbaa !4
+ %niter508.next.3 = add i64 %niter508, 4
+ %niter508.ncmp.3 = icmp eq i64 %niter508.next.3, %unroll_iter507
+ br i1 %niter508.ncmp.3, label %sw.epilog201.loopexit484.unr-lcssa, label %for.body140, !llvm.loop !24
+
+sw.bb149: ; preds = %for.cond.cleanup104
+ %puts315 = call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
+ %43 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp153360 = icmp sgt i32 %43, 0
+ br i1 %cmp153360, label %for.body156.preheader, label %sw.epilog201
+
+for.body156.preheader: ; preds = %sw.bb149
+ %wide.trip.count412 = zext nneg i32 %43 to i64
+ %xtraiter499 = and i64 %wide.trip.count412, 3
+ %44 = icmp ult i32 %43, 4
+ br i1 %44, label %sw.epilog201.loopexit485.unr-lcssa, label %for.body156.preheader.new
+
+for.body156.preheader.new: ; preds = %for.body156.preheader
+ %unroll_iter502 = and i64 %wide.trip.count412, 2147483644
+ br label %for.body156
+
+for.body156: ; preds = %for.body156, %for.body156.preheader.new
+ %indvars.iv407 = phi i64 [ 0, %for.body156.preheader.new ], [ %indvars.iv.next408.3, %for.body156 ]
+ %niter503 = phi i64 [ 0, %for.body156.preheader.new ], [ %niter503.next.3, %for.body156 ]
+ %45 = trunc nuw nsw i64 %indvars.iv407 to i32
+ %mul158316 = mul i32 %45, %45
+ %46 = trunc i64 %indvars.iv407 to i32
+ %47 = add i32 %46, -1
+ %sub160 = mul i32 %mul158316, %47
+ %arrayidx162 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv407
+ store i32 %sub160, ptr %arrayidx162, align 8, !tbaa !4
+ %indvars.iv.next408 = or disjoint i64 %indvars.iv407, 1
+ %48 = trunc nuw nsw i64 %indvars.iv.next408 to i32
+ %mul158316.1 = mul i32 %48, %48
+ %49 = trunc i64 %indvars.iv.next408 to i32
+ %50 = add nsw i32 %49, -1
+ %sub160.1 = mul i32 %mul158316.1, %50
+ %arrayidx162.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408
+ store i32 %sub160.1, ptr %arrayidx162.1, align 4, !tbaa !4
+ %indvars.iv.next408.1 = or disjoint i64 %indvars.iv407, 2
+ %51 = trunc nuw nsw i64 %indvars.iv.next408.1 to i32
+ %mul158316.2 = mul i32 %51, %51
+ %52 = trunc i64 %indvars.iv.next408.1 to i32
+ %53 = add nsw i32 %52, -1
+ %sub160.2 = mul i32 %mul158316.2, %53
+ %arrayidx162.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408.1
+ store i32 %sub160.2, ptr %arrayidx162.2, align 8, !tbaa !4
+ %indvars.iv.next408.2 = or disjoint i64 %indvars.iv407, 3
+ %54 = trunc nuw nsw i64 %indvars.iv.next408.2 to i32
+ %mul158316.3 = mul i32 %54, %54
+ %55 = trunc i64 %indvars.iv.next408.2 to i32
+ %56 = add nsw i32 %55, -1
+ %sub160.3 = mul i32 %mul158316.3, %56
+ %arrayidx162.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408.2
+ store i32 %sub160.3, ptr %arrayidx162.3, align 4, !tbaa !4
+ %indvars.iv.next408.3 = add nuw nsw i64 %indvars.iv407, 4
+ %niter503.next.3 = add i64 %niter503, 4
+ %niter503.ncmp.3 = icmp eq i64 %niter503.next.3, %unroll_iter502
+ br i1 %niter503.ncmp.3, label %sw.epilog201.loopexit485.unr-lcssa, label %for.body156, !llvm.loop !25
+
+sw.bb166: ; preds = %for.cond.cleanup104
+ %puts311 = call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
+ %57 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp170358 = icmp sgt i32 %57, 0
+ br i1 %cmp170358, label %for.body173.preheader, label %sw.epilog201
+
+for.body173.preheader: ; preds = %sw.bb166
+ %wide.trip.count405 = zext nneg i32 %57 to i64
+ %xtraiter494 = and i64 %wide.trip.count405, 3
+ %58 = icmp ult i32 %57, 4
+ br i1 %58, label %sw.epilog201.loopexit486.unr-lcssa, label %for.body173.preheader.new
+
+for.body173.preheader.new: ; preds = %for.body173.preheader
+ %unroll_iter497 = and i64 %wide.trip.count405, 2147483644
+ br label %for.body173
+
+for.body173: ; preds = %for.body173, %for.body173.preheader.new
+ %indvars.iv401 = phi i64 [ 0, %for.body173.preheader.new ], [ %indvars.iv.next402.3, %for.body173 ]
+ %niter498 = phi i64 [ 0, %for.body173.preheader.new ], [ %niter498.next.3, %for.body173 ]
+ %indvars.iv.next402 = or disjoint i64 %indvars.iv401, 1
+ %indvars403 = trunc i64 %indvars.iv.next402 to i32
+ %59 = trunc nuw nsw i64 %indvars.iv401 to i32
+ %mul175312 = mul i32 %indvars403, %59
+ %add177314 = or disjoint i32 %mul175312, 3
+ %add179 = mul i32 %add177314, %59
+ %arrayidx181 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv401
+ store i32 %add179, ptr %arrayidx181, align 8, !tbaa !4
+ %indvars.iv.next402.1 = or disjoint i64 %indvars.iv401, 2
+ %indvars403.1 = trunc i64 %indvars.iv.next402.1 to i32
+ %60 = trunc nuw nsw i64 %indvars.iv.next402 to i32
+ %mul175312.1 = mul i32 %indvars403.1, %60
+ %add177314.1 = add i32 %mul175312.1, 3
+ %add179.1 = mul i32 %add177314.1, %60
+ %arrayidx181.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402
+ store i32 %add179.1, ptr %arrayidx181.1, align 4, !tbaa !4
+ %indvars.iv.next402.2 = or disjoint i64 %indvars.iv401, 3
+ %indvars403.2 = trunc i64 %indvars.iv.next402.2 to i32
+ %61 = trunc nuw nsw i64 %indvars.iv.next402.1 to i32
+ %mul175312.2 = mul i32 %indvars403.2, %61
+ %add177314.2 = add i32 %mul175312.2, 3
+ %add179.2 = mul i32 %add177314.2, %61
+ %arrayidx181.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402.1
+ store i32 %add179.2, ptr %arrayidx181.2, align 8, !tbaa !4
+ %indvars.iv.next402.3 = add nuw nsw i64 %indvars.iv401, 4
+ %indvars403.3 = trunc i64 %indvars.iv.next402.3 to i32
+ %62 = trunc nuw nsw i64 %indvars.iv.next402.2 to i32
+ %mul175312.3 = mul i32 %indvars403.3, %62
+ %add177314.3 = or disjoint i32 %mul175312.3, 3
+ %add179.3 = mul i32 %add177314.3, %62
+ %arrayidx181.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402.2
+ store i32 %add179.3, ptr %arrayidx181.3, align 4, !tbaa !4
+ %niter498.next.3 = add i64 %niter498, 4
+ %niter498.ncmp.3 = icmp eq i64 %niter498.next.3, %unroll_iter497
+ br i1 %niter498.ncmp.3, label %sw.epilog201.loopexit486.unr-lcssa, label %for.body173, !llvm.loop !26
+
+sw.bb185: ; preds = %for.cond.cleanup104
+ %puts309 = call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
+ %63 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp189356 = icmp sgt i32 %63, 0
+ br i1 %cmp189356, label %for.body192.preheader, label %sw.epilog201
+
+for.body192.preheader: ; preds = %sw.bb185
+ %wide.trip.count399 = zext nneg i32 %63 to i64
+ %xtraiter489 = and i64 %wide.trip.count399, 3
+ %64 = icmp ult i32 %63, 4
+ br i1 %64, label %sw.epilog201.loopexit487.unr-lcssa, label %for.body192.preheader.new
+
+for.body192.preheader.new: ; preds = %for.body192.preheader
+ %unroll_iter492 = and i64 %wide.trip.count399, 2147483644
+ br label %for.body192
+
+for.body192: ; preds = %for.body192, %for.body192.preheader.new
+ %indvars.iv394 = phi i64 [ 0, %for.body192.preheader.new ], [ %indvars.iv.next395.3, %for.body192 ]
+ %niter493 = phi i64 [ 0, %for.body192.preheader.new ], [ %niter493.next.3, %for.body192 ]
+ %indvars398 = trunc i64 %indvars.iv394 to i32
+ %mul194310 = or disjoint i32 %indvars398, 3
+ %add195 = mul i32 %mul194310, %indvars398
+ %arrayidx197 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv394
+ store i32 %add195, ptr %arrayidx197, align 8, !tbaa !4
+ %indvars.iv.next395 = or disjoint i64 %indvars.iv394, 1
+ %indvars398.1 = trunc i64 %indvars.iv.next395 to i32
+ %mul194310.1 = add nuw i32 %indvars398.1, 3
+ %add195.1 = mul i32 %mul194310.1, %indvars398.1
+ %arrayidx197.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395
+ store i32 %add195.1, ptr %arrayidx197.1, align 4, !tbaa !4
+ %indvars.iv.next395.1 = or disjoint i64 %indvars.iv394, 2
+ %indvars398.2 = trunc i64 %indvars.iv.next395.1 to i32
+ %mul194310.2 = add nuw i32 %indvars398.2, 3
+ %add195.2 = mul i32 %mul194310.2, %indvars398.2
+ %arrayidx197.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395.1
+ store i32 %add195.2, ptr %arrayidx197.2, align 8, !tbaa !4
+ %indvars.iv.next395.2 = or disjoint i64 %indvars.iv394, 3
+ %indvars398.3 = trunc i64 %indvars.iv.next395.2 to i32
+ %mul194310.3 = add nuw i32 %indvars398.3, 3
+ %add195.3 = mul i32 %mul194310.3, %indvars398.3
+ %arrayidx197.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395.2
+ store i32 %add195.3, ptr %arrayidx197.3, align 4, !tbaa !4
+ %indvars.iv.next395.3 = add nuw nsw i64 %indvars.iv394, 4
+ %niter493.next.3 = add i64 %niter493, 4
+ %niter493.ncmp.3 = icmp eq i64 %niter493.next.3, %unroll_iter492
+ br i1 %niter493.ncmp.3, label %sw.epilog201.loopexit487.unr-lcssa, label %for.body192, !llvm.loop !27
+
+sw.epilog201.loopexit.unr-lcssa: ; preds = %for.body120, %for.body120.preheader
+ %indvars.iv420.unr = phi i64 [ 0, %for.body120.preheader ], [ %indvars.iv.next421.3, %for.body120 ]
+ %lcmp.mod511.not = icmp eq i64 %xtraiter509, 0
+ br i1 %lcmp.mod511.not, label %sw.epilog201, label %for.body120.epil
+
+for.body120.epil: ; preds = %sw.epilog201.loopexit.unr-lcssa, %for.body120.epil
+ %indvars.iv420.epil = phi i64 [ %indvars.iv.next421.epil, %for.body120.epil ], [ %indvars.iv420.unr, %sw.epilog201.loopexit.unr-lcssa ]
+ %epil.iter510 = phi i64 [ %epil.iter510.next, %for.body120.epil ], [ 0, %sw.epilog201.loopexit.unr-lcssa ]
+ %indvars425.epil = trunc i64 %indvars.iv420.epil to i32
+ %mul121.epil = mul nuw nsw i32 %indvars425.epil, %indvars425.epil
+ %mul122322.epil = add nuw i32 %mul121.epil, 1
+ %mul123321.epil = mul i32 %mul122322.epil, %indvars425.epil
+ %add125323.epil = add i32 %mul123321.epil, 3
+ %add127.epil = mul i32 %add125323.epil, %indvars425.epil
+ %arrayidx129.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv420.epil
+ store i32 %add127.epil, ptr %arrayidx129.epil, align 4, !tbaa !4
+ %indvars.iv.next421.epil = add nuw nsw i64 %indvars.iv420.epil, 1
+ %epil.iter510.next = add i64 %epil.iter510, 1
+ %epil.iter510.cmp.not = icmp eq i64 %epil.iter510.next, %xtraiter509
+ br i1 %epil.iter510.cmp.not, label %sw.epilog201, label %for.body120.epil, !llvm.loop !28
+
+sw.epilog201.loopexit484.unr-lcssa: ; preds = %for.body140, %for.body140.preheader
+ %indvars.iv414.unr = phi i64 [ 0, %for.body140.preheader ], [ %indvars.iv.next415.3, %for.body140 ]
+ %lcmp.mod506.not = icmp eq i64 %xtraiter504, 0
+ br i1 %lcmp.mod506.not, label %sw.epilog201, label %for.body140.epil
+
+for.body140.epil: ; preds = %sw.epilog201.loopexit484.unr-lcssa, %for.body140.epil
+ %indvars.iv414.epil = phi i64 [ %indvars.iv.next415.epil, %for.body140.epil ], [ %indvars.iv414.unr, %sw.epilog201.loopexit484.unr-lcssa ]
+ %epil.iter505 = phi i64 [ %epil.iter505.next, %for.body140.epil ], [ 0, %sw.epilog201.loopexit484.unr-lcssa ]
+ %indvars.iv.next415.epil = add nuw nsw i64 %indvars.iv414.epil, 1
+ %indvars416.epil = trunc i64 %indvars.iv.next415.epil to i32
+ %65 = trunc nuw nsw i64 %indvars.iv414.epil to i32
+ %add142.epil = mul i32 %indvars416.epil, %65
+ %add143.epil = add nsw i32 %add142.epil, 3
+ %arrayidx145.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv414.epil
+ store i32 %add143.epil, ptr %arrayidx145.epil, align 4, !tbaa !4
+ %epil.iter505.next = add i64 %epil.iter505, 1
+ %epil.iter505.cmp.not = icmp eq i64 %epil.iter505.next, %xtraiter504
+ br i1 %epil.iter505.cmp.not, label %sw.epilog201, label %for.body140.epil, !llvm.loop !29
+
+sw.epilog201.loopexit485.unr-lcssa: ; preds = %for.body156, %for.body156.preheader
+ %indvars.iv407.unr = phi i64 [ 0, %for.body156.preheader ], [ %indvars.iv.next408.3, %for.body156 ]
+ %lcmp.mod501.not = icmp eq i64 %xtraiter499, 0
+ br i1 %lcmp.mod501.not, label %sw.epilog201, label %for.body156.epil
+
+for.body156.epil: ; preds = %sw.epilog201.loopexit485.unr-lcssa, %for.body156.epil
+ %indvars.iv407.epil = phi i64 [ %indvars.iv.next408.epil, %for.body156.epil ], [ %indvars.iv407.unr, %sw.epilog201.loopexit485.unr-lcssa ]
+ %epil.iter500 = phi i64 [ %epil.iter500.next, %for.body156.epil ], [ 0, %sw.epilog201.loopexit485.unr-lcssa ]
+ %66 = trunc nuw nsw i64 %indvars.iv407.epil to i32
+ %mul158316.epil = mul i32 %66, %66
+ %67 = trunc i64 %indvars.iv407.epil to i32
+ %68 = add i32 %67, -1
+ %sub160.epil = mul i32 %mul158316.epil, %68
+ %arrayidx162.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv407.epil
+ store i32 %sub160.epil, ptr %arrayidx162.epil, align 4, !tbaa !4
+ %indvars.iv.next408.epil = add nuw nsw i64 %indvars.iv407.epil, 1
+ %epil.iter500.next = add i64 %epil.iter500, 1
+ %epil.iter500.cmp.not = icmp eq i64 %epil.iter500.next, %xtraiter499
+ br i1 %epil.iter500.cmp.not, label %sw.epilog201, label %for.body156.epil, !llvm.loop !30
+
+sw.epilog201.loopexit486.unr-lcssa: ; preds = %for.body173, %for.body173.preheader
+ %indvars.iv401.unr = phi i64 [ 0, %for.body173.preheader ], [ %indvars.iv.next402.3, %for.body173 ]
+ %lcmp.mod496.not = icmp eq i64 %xtraiter494, 0
+ br i1 %lcmp.mod496.not, label %sw.epilog201, label %for.body173.epil
+
+for.body173.epil: ; preds = %sw.epilog201.loopexit486.unr-lcssa, %for.body173.epil
+ %indvars.iv401.epil = phi i64 [ %indvars.iv.next402.epil, %for.body173.epil ], [ %indvars.iv401.unr, %sw.epilog201.loopexit486.unr-lcssa ]
+ %epil.iter495 = phi i64 [ %epil.iter495.next, %for.body173.epil ], [ 0, %sw.epilog201.loopexit486.unr-lcssa ]
+ %indvars.iv.next402.epil = add nuw nsw i64 %indvars.iv401.epil, 1
+ %indvars403.epil = trunc i64 %indvars.iv.next402.epil to i32
+ %69 = trunc nuw nsw i64 %indvars.iv401.epil to i32
+ %mul175312.epil = mul i32 %indvars403.epil, %69
+ %add177314.epil = add i32 %mul175312.epil, 3
+ %add179.epil = mul i32 %add177314.epil, %69
+ %arrayidx181.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv401.epil
+ store i32 %add179.epil, ptr %arrayidx181.epil, align 4, !tbaa !4
+ %epil.iter495.next = add i64 %epil.iter495, 1
+ %epil.iter495.cmp.not = icmp eq i64 %epil.iter495.next, %xtraiter494
+ br i1 %epil.iter495.cmp.not, label %sw.epilog201, label %for.body173.epil, !llvm.loop !31
+
+sw.epilog201.loopexit487.unr-lcssa: ; preds = %for.body192, %for.body192.preheader
+ %indvars.iv394.unr = phi i64 [ 0, %for.body192.preheader ], [ %indvars.iv.next395.3, %for.body192 ]
+ %lcmp.mod491.not = icmp eq i64 %xtraiter489, 0
+ br i1 %lcmp.mod491.not, label %sw.epilog201, label %for.body192.epil
+
+for.body192.epil: ; preds = %sw.epilog201.loopexit487.unr-lcssa, %for.body192.epil
+ %indvars.iv394.epil = phi i64 [ %indvars.iv.next395.epil, %for.body192.epil ], [ %indvars.iv394.unr, %sw.epilog201.loopexit487.unr-lcssa ]
+ %epil.iter490 = phi i64 [ %epil.iter490.next, %for.body192.epil ], [ 0, %sw.epilog201.loopexit487.unr-lcssa ]
+ %indvars398.epil = trunc i64 %indvars.iv394.epil to i32
+ %mul194310.epil = add nuw i32 %indvars398.epil, 3
+ %add195.epil = mul i32 %mul194310.epil, %indvars398.epil
+ %arrayidx197.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv394.epil
+ store i32 %add195.epil, ptr %arrayidx197.epil, align 4, !tbaa !4
+ %indvars.iv.next395.epil = add nuw nsw i64 %indvars.iv394.epil, 1
+ %epil.iter490.next = add i64 %epil.iter490, 1
+ %epil.iter490.cmp.not = icmp eq i64 %epil.iter490.next, %xtraiter489
+ br i1 %epil.iter490.cmp.not, label %sw.epilog201, label %for.body192.epil, !llvm.loop !32
+
+sw.epilog201: ; preds = %sw.epilog201.loopexit487.unr-lcssa, %for.body192.epil, %sw.epilog201.loopexit486.unr-lcssa, %for.body173.epil, %sw.epilog201.loopexit485.unr-lcssa, %for.body156.epil, %sw.epilog201.loopexit484.unr-lcssa, %for.body140.epil, %sw.epilog201.loopexit.unr-lcssa, %for.body120.epil, %sw.bb185, %sw.bb166, %sw.bb149, %sw.bb133, %sw.bb113, %for.cond.cleanup104
+ call void @func3()
+ unreachable
+
+if.else202: ; preds = %for.cond.cleanup
+ %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %70 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp206352 = icmp sgt i32 %70, 0
+ br i1 %cmp206352, label %for.body209, label %for.cond.cleanup208
+
+for.cond.cleanup208: ; preds = %for.body209, %if.else202
+ call void @func2()
+ unreachable
+
+for.body209: ; preds = %if.else202, %for.body209
+ %indvars.iv386 = phi i64 [ %indvars.iv.next387, %for.body209 ], [ 0, %if.else202 ]
+ %arrayidx211 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv386
+ %71 = load i32, ptr %arrayidx211, align 4, !tbaa !4
+ %call212 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %71)
+ %indvars.iv.next387 = add nuw nsw i64 %indvars.iv386, 1
+ %72 = load i32, ptr %len, align 4, !tbaa !4
+ %73 = sext i32 %72 to i64
+ %cmp206 = icmp slt i64 %indvars.iv.next387, %73
+ br i1 %cmp206, label %for.body209, label %for.cond.cleanup208, !llvm.loop !33
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+entry:
+; CHECK: larl %r1, buf1
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r11, 0(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r3, 16(%r1)
+; CHECK: stg %r3, 0(%r15)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: br %r2
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.34)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.33)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+attributes #5 = { nounwind }
+attributes #6 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = distinct !{!8, !9}
+!9 = !{!"llvm.loop.unroll.disable"}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
+!13 = distinct !{!13, !11}
+!14 = distinct !{!14, !11}
+!15 = distinct !{!15, !11}
+!16 = distinct !{!16, !11}
+!17 = distinct !{!17, !9}
+!18 = distinct !{!18, !9}
+!19 = distinct !{!19, !9}
+!20 = distinct !{!20, !9}
+!21 = distinct !{!21, !9}
+!22 = distinct !{!22, !11}
+!23 = distinct !{!23, !11}
+!24 = distinct !{!24, !11}
+!25 = distinct !{!25, !11}
+!26 = distinct !{!26, !11}
+!27 = distinct !{!27, !11}
+!28 = distinct !{!28, !9}
+!29 = distinct !{!29, !9}
+!30 = distinct !{!30, !9}
+!31 = distinct !{!31, !9}
+!32 = distinct !{!32, !9}
+!33 = distinct !{!33, !11}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-03.ll
new file mode 100644
index 00000000000000..d2a3c85576137e
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-03.ll
@@ -0,0 +1,74 @@
+;Test -mbackchain longjmp load from jmp_buf.
+; Frame pointer from Slot 1.
+; Jump address from Slot 2.
+; Backchain Value from Slot 3.
+; Stack Pointer from Slot 4.
+; Literal Pool Pointer from Slot 5.
+
+; RUN: llc < %s | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-backchain-02.c'
+source_filename = "builtin-setjmp-longjmp-backchain-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at str = private unnamed_addr constant [9 x i8] c"call foo\00", align 1
+ at str.2 = private unnamed_addr constant [7 x i8] c"return\00", align 1
+
+; Function Attrs: noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+; Function Attrs: nounwind
+define dso_local noundef signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #2 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %tobool.not = icmp eq i32 %0, 0
+ br i1 %tobool.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %puts2 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.2)
+ ret i32 0
+
+if.end: ; preds = %entry
+; CHECK: stmg %r11, %r15, 88(%r15)
+; CHECK: larl %r1, buf
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r11, 0(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r3, 16(%r1)
+; CHECK: stg %r3, 0(%r15)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: br %r2
+
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #4
+
+attributes #0 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+attributes #2 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { nounwind }
+attributes #4 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-00.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-00.ll
new file mode 100644
index 00000000000000..47c62f3f40396b
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-00.ll
@@ -0,0 +1,93 @@
+; Test output for inline Literal Pool.
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+; CHECK: value_ptr is 954219
+; CHECK: value_ptr is 954219
+; CHECK: value_ptr is 420420
+
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-00.c'
+source_filename = "builtin-setjmp-longjmp-literal-pool-00.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str = private unnamed_addr constant [17 x i8] c"value_ptr is %d\0A\00", align 2
+
+; Function Attrs: noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #2 {
+entry:
+ %0 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #3, !srcloc !4
+ %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %1, 0
+ %2 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 noundef signext %2)
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+
+if.else: ; preds = %entry
+ %add.ptr2 = getelementptr inbounds i8, ptr %0, i64 40
+ %3 = load i32, ptr %add.ptr2, align 4, !tbaa !5
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 noundef signext %3)
+ ret i32 0
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+
+attributes #0 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+attributes #2 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { nounwind }
+attributes #4 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{i64 751}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-01.ll
new file mode 100644
index 00000000000000..8120fa2a6f6fc5
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-01.ll
@@ -0,0 +1,202 @@
+; Test Literal Pool Register R13.
+; Test the output.
+; FIXME:
+
+; Correct Output is:
+;First __builtin_setjmp in func1
+;Second __builtin_setjmp in func1
+;Returned from func4
+;value_ptr : 954219
+;Returned from func3
+;value_ptr: 420420
+
+; TODO: -mbackchain
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-01.c'
+
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+
+source_filename = "builtin-setjmp-longjmp-literal-pool-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.13 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.14 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.15 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.16 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.17 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.18 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: value_ptr : 954219
+; CHECK: Returned from func3
+; CHECK: value_ptr: 954219
+
+ %0 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #4, !srcloc !4
+ %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp = icmp eq i32 %1, 0
+ br i1 %cmp, label %if.then, label %if.else7
+
+if.then: ; preds = %entry
+ %puts13 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp1 = icmp eq i32 %2, 0
+ br i1 %cmp1, label %if.then2, label %if.else
+
+if.then2: ; preds = %if.then
+ %puts15 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts14 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %3 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %3)
+ tail call void @func3()
+ unreachable
+
+if.else7: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %4 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %4)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %1 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #4, !srcloc !4
+ %add.ptr.i = getelementptr inbounds i8, ptr %1, i64 8
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp.i = icmp eq i32 %2, 0
+ br i1 %cmp.i, label %if.then.i, label %if.else7.i
+
+if.then.i: ; preds = %if.then
+ %puts13.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %3 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp1.i = icmp eq i32 %3, 0
+ br i1 %cmp1.i, label %if.then2.i, label %if.else.i
+
+if.then2.i: ; preds = %if.then.i
+ %puts15.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ tail call void @func4()
+ unreachable
+
+if.else.i: ; preds = %if.then.i
+ %puts14.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %4 = load i32, ptr %add.ptr.i, align 4, !tbaa !5
+ %call5.i = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %4)
+ tail call void @func3()
+ unreachable
+
+if.else7.i: ; preds = %if.then
+ %puts.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %5 = load i32, ptr %add.ptr.i, align 4, !tbaa !5
+ %call9.i = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %5)
+ tail call void @func2()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{i64 1166}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-02.ll
new file mode 100644
index 00000000000000..2373d5e883874d
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-02.ll
@@ -0,0 +1,278 @@
+; Test Literal Pool Register R13.
+; Test the output.
+; FIXME:
+
+; Correct Output is:
+
+;First __builtin_setjmp in func1
+;Second __builtin_setjmp in func1
+;Returned from func4
+;value_ptr : 954219
+;arr: 954219
+;arr: 466232
+;arr: 955551
+;arr: 687823
+;arr: 555123
+;arr: 777723
+;arr: 985473
+;arr: 190346
+;arr: 420420
+;arr: 732972
+;Returned from func3
+;value_ptr: 971166
+;arr: 971166
+;arr: 123454
+;arr: 451233
+;arr: 954219
+;arr: 466232
+;arr: 955551
+;arr: 687823
+;arr: 555123
+;arr: 123454
+;arr: 451233
+
+; TODO: -mbackchain
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-01.c'
+
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+
+
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-02.c'
+source_filename = "builtin-setjmp-longjmp-literal-pool-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".LC202:"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.13 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.15 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.17 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.18 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: Returned from func4
+; CHECK: value_ptr : 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+; CHECK: Returned from func3
+; CHECK: value_ptr: 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+
+ %0 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #4, !srcloc !4
+ %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
+ %.sroa.0.0.copyload = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %.sroa.4.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 12
+ %.sroa.4.0.copyload = load i32, ptr %.sroa.4.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.6.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 16
+ %.sroa.6.0.copyload = load i32, ptr %.sroa.6.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.8.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 20
+ %.sroa.8.0.copyload = load i32, ptr %.sroa.8.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.10.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 24
+ %.sroa.10.0.copyload = load i32, ptr %.sroa.10.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.12.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 28
+ %.sroa.12.0.copyload = load i32, ptr %.sroa.12.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.14.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 32
+ %.sroa.14.0.copyload = load i32, ptr %.sroa.14.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.16.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 36
+ %.sroa.16.0.copyload = load i32, ptr %.sroa.16.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.18.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 40
+ %.sroa.18.0.copyload = load i32, ptr %.sroa.18.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.20.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 44
+ %.sroa.20.0.copyload = load i32, ptr %.sroa.20.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp2 = icmp eq i32 %1, 0
+ br i1 %cmp2, label %if.then, label %if.else32
+
+if.then: ; preds = %entry
+ %puts64 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp3 = icmp eq i32 %2, 0
+ br i1 %cmp3, label %if.then4, label %if.else
+
+if.then4: ; preds = %if.then
+ %puts66 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts65 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ %3 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %3)
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.0.0.copyload)
+ %call15.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.4.0.copyload)
+ %call15.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.6.0.copyload)
+ %call15.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.8.0.copyload)
+ %call15.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.10.0.copyload)
+ %call15.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.12.0.copyload)
+ %call15.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.14.0.copyload)
+ %call15.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.16.0.copyload)
+ %call15.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.18.0.copyload)
+ %call15.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.20.0.copyload)
+ %4 = tail call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #4, !srcloc !9
+ tail call void @func3()
+ unreachable
+
+if.else32: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %5 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call34 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %5)
+ %call42 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.0.0.copyload)
+ %call42.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.4.0.copyload)
+ %call42.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.6.0.copyload)
+ %call42.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.8.0.copyload)
+ %call42.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.10.0.copyload)
+ %call42.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.12.0.copyload)
+ %call42.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.14.0.copyload)
+ %call42.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.16.0.copyload)
+ %call42.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.18.0.copyload)
+ %call42.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.20.0.copyload)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{i64 1661}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
+!9 = !{i64 2337}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-03.ll
new file mode 100644
index 00000000000000..3adc7cd4bd284b
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-03.ll
@@ -0,0 +1,416 @@
+; Test Literal Pool Register R13.
+; Test the output.
+; Gives Correct Result.
+; FIXME: How to pass stdin input to llvm-lit
+; TODO: -mbackchain option.
+
+; RUN: clang -o %t %s
+; RUN: %t < 10| FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-03.c'
+source_filename = "builtin-setjmp-longjmp-literal-pool-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".LC202:"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
+ at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
+ at .str.8 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.14 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.15 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.17 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.18 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.19 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.20 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.21 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+In func4
+; CHECK: Returned from func4
+; CHECK: value_ptr : 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+In func3
+; CHECK: Returned from func3
+; CHECK: value_ptr: 420420
+; CHECK: arr: 971166
+; CHECK: arr: 123454
+; CHECK: arr: 451233
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 123454
+; CHECK: arr: 451233
+
+ %len = alloca i32, align 4
+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
+ store i32 0, ptr %len, align 4, !tbaa !4
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
+ %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
+ %0 = alloca [40 x i8], align 8
+ %1 = call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #5, !srcloc !8
+ %add.ptr = getelementptr inbounds i8, ptr %1, i64 8
+ %2 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp70 = icmp sgt i32 %2, 0
+ br i1 %cmp70, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %wide.trip.count = zext nneg i32 %2 to i64
+ %xtraiter = and i64 %wide.trip.count, 3
+ %3 = icmp ult i32 %2, 4
+ br i1 %3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
+
+for.body.preheader.new: ; preds = %for.body.preheader
+ %unroll_iter = and i64 %wide.trip.count, 2147483644
+ br label %for.body
+
+for.cond.cleanup.loopexit.unr-lcssa: ; preds = %for.body, %for.body.preheader
+ %indvars.iv.unr = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next.3, %for.body ]
+ %lcmp.mod.not = icmp eq i64 %xtraiter, 0
+ br i1 %lcmp.mod.not, label %for.cond.cleanup, label %for.body.epil
+
+for.body.epil: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil
+ %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %for.body.epil ], [ %indvars.iv.unr, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %4 = trunc nuw nsw i64 %indvars.iv.epil to i32
+ %rem.epil = urem i32 %4, 10
+ %idx.ext.epil = zext nneg i32 %rem.epil to i64
+ %add.ptr2.epil = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext.epil
+ %5 = load i32, ptr %add.ptr2.epil, align 4, !tbaa !4
+ %arrayidx.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.epil
+ store i32 %5, ptr %arrayidx.epil, align 4, !tbaa !4
+ %indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
+ %epil.iter.next = add i64 %epil.iter, 1
+ %epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
+ br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !9
+
+for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
+ %6 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %6, 0
+ br i1 %cmp3, label %if.then, label %if.else35
+
+for.body: ; preds = %for.body, %for.body.preheader.new
+ %indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
+ %niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
+ %7 = trunc nuw nsw i64 %indvars.iv to i32
+ %rem = urem i32 %7, 10
+ %idx.ext = zext nneg i32 %rem to i64
+ %add.ptr2 = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext
+ %8 = load i32, ptr %add.ptr2, align 4, !tbaa !4
+ %arrayidx = getelementptr inbounds i32, ptr %0, i64 %indvars.iv
+ store i32 %8, ptr %arrayidx, align 8, !tbaa !4
+ %indvars.iv.next = or disjoint i64 %indvars.iv, 1
+ %9 = trunc nuw nsw i64 %indvars.iv.next to i32
+ %rem.1 = urem i32 %9, 10
+ %idx.ext.1 = zext nneg i32 %rem.1 to i64
+ %add.ptr2.1 = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext.1
+ %10 = load i32, ptr %add.ptr2.1, align 4, !tbaa !4
+ %arrayidx.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next
+ store i32 %10, ptr %arrayidx.1, align 4, !tbaa !4
+ %indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
+ %11 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
+ %rem.2 = urem i32 %11, 10
+ %idx.ext.2 = zext nneg i32 %rem.2 to i64
+ %add.ptr2.2 = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext.2
+ %12 = load i32, ptr %add.ptr2.2, align 4, !tbaa !4
+ %arrayidx.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.1
+ store i32 %12, ptr %arrayidx.2, align 8, !tbaa !4
+ %indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
+ %13 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
+ %rem.3 = urem i32 %13, 10
+ %idx.ext.3 = zext nneg i32 %rem.3 to i64
+ %add.ptr2.3 = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext.3
+ %14 = load i32, ptr %add.ptr2.3, align 4, !tbaa !4
+ %arrayidx.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.2
+ store i32 %14, ptr %arrayidx.3, align 4, !tbaa !4
+ %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
+ %niter.next.3 = add i64 %niter, 4
+ %niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
+ br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !11
+
+if.then: ; preds = %for.cond.cleanup
+ %puts67 = call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %15 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %15, 0
+ br i1 %cmp5, label %if.then6, label %if.else
+
+if.then6: ; preds = %if.then
+ %puts69 = call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts68 = call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %16 = load i32, ptr %add.ptr, align 4, !tbaa !4
+ %call9 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %16)
+ %17 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp1274 = icmp sgt i32 %17, 0
+ br i1 %cmp1274, label %for.body14, label %for.cond.cleanup13
+
+for.cond.cleanup13: ; preds = %for.body14, %if.else
+ %18 = call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #5, !srcloc !13
+ %add.ptr21 = getelementptr inbounds i8, ptr %18, i64 8
+ %19 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp2476 = icmp sgt i32 %19, 0
+ br i1 %cmp2476, label %for.body26.preheader, label %for.cond.cleanup25
+
+for.body26.preheader: ; preds = %for.cond.cleanup13
+ %wide.trip.count88 = zext nneg i32 %19 to i64
+ %xtraiter90 = and i64 %wide.trip.count88, 3
+ %20 = icmp ult i32 %19, 4
+ br i1 %20, label %for.cond.cleanup25.loopexit.unr-lcssa, label %for.body26.preheader.new
+
+for.body26.preheader.new: ; preds = %for.body26.preheader
+ %unroll_iter93 = and i64 %wide.trip.count88, 2147483644
+ br label %for.body26
+
+for.body14: ; preds = %if.else, %for.body14
+ %indvars.iv82 = phi i64 [ %indvars.iv.next83, %for.body14 ], [ 0, %if.else ]
+ %arrayidx16 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv82
+ %21 = load i32, ptr %arrayidx16, align 4, !tbaa !4
+ %call17 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %21)
+ %indvars.iv.next83 = add nuw nsw i64 %indvars.iv82, 1
+ %22 = load i32, ptr %len, align 4, !tbaa !4
+ %23 = sext i32 %22 to i64
+ %cmp12 = icmp slt i64 %indvars.iv.next83, %23
+ br i1 %cmp12, label %for.body14, label %for.cond.cleanup13, !llvm.loop !14
+
+for.cond.cleanup25.loopexit.unr-lcssa: ; preds = %for.body26, %for.body26.preheader
+ %indvars.iv85.unr = phi i64 [ 0, %for.body26.preheader ], [ %indvars.iv.next86.3, %for.body26 ]
+ %lcmp.mod92.not = icmp eq i64 %xtraiter90, 0
+ br i1 %lcmp.mod92.not, label %for.cond.cleanup25, label %for.body26.epil
+
+for.body26.epil: ; preds = %for.cond.cleanup25.loopexit.unr-lcssa, %for.body26.epil
+ %indvars.iv85.epil = phi i64 [ %indvars.iv.next86.epil, %for.body26.epil ], [ %indvars.iv85.unr, %for.cond.cleanup25.loopexit.unr-lcssa ]
+ %epil.iter91 = phi i64 [ %epil.iter91.next, %for.body26.epil ], [ 0, %for.cond.cleanup25.loopexit.unr-lcssa ]
+ %24 = trunc nuw nsw i64 %indvars.iv85.epil to i32
+ %rem27.epil = urem i32 %24, 10
+ %idx.ext28.epil = zext nneg i32 %rem27.epil to i64
+ %add.ptr29.epil = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28.epil
+ %25 = load i32, ptr %add.ptr29.epil, align 4, !tbaa !4
+ %arrayidx31.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv85.epil
+ store i32 %25, ptr %arrayidx31.epil, align 4, !tbaa !4
+ %indvars.iv.next86.epil = add nuw nsw i64 %indvars.iv85.epil, 1
+ %epil.iter91.next = add i64 %epil.iter91, 1
+ %epil.iter91.cmp.not = icmp eq i64 %epil.iter91.next, %xtraiter90
+ br i1 %epil.iter91.cmp.not, label %for.cond.cleanup25, label %for.body26.epil, !llvm.loop !15
+
+for.cond.cleanup25: ; preds = %for.cond.cleanup25.loopexit.unr-lcssa, %for.body26.epil, %for.cond.cleanup13
+ call void @func3()
+ unreachable
+
+for.body26: ; preds = %for.body26, %for.body26.preheader.new
+ %indvars.iv85 = phi i64 [ 0, %for.body26.preheader.new ], [ %indvars.iv.next86.3, %for.body26 ]
+ %niter94 = phi i64 [ 0, %for.body26.preheader.new ], [ %niter94.next.3, %for.body26 ]
+ %26 = trunc nuw nsw i64 %indvars.iv85 to i32
+ %rem27 = urem i32 %26, 10
+ %idx.ext28 = zext nneg i32 %rem27 to i64
+ %add.ptr29 = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28
+ %27 = load i32, ptr %add.ptr29, align 4, !tbaa !4
+ %arrayidx31 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv85
+ store i32 %27, ptr %arrayidx31, align 8, !tbaa !4
+ %indvars.iv.next86 = or disjoint i64 %indvars.iv85, 1
+ %28 = trunc nuw nsw i64 %indvars.iv.next86 to i32
+ %rem27.1 = urem i32 %28, 10
+ %idx.ext28.1 = zext nneg i32 %rem27.1 to i64
+ %add.ptr29.1 = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28.1
+ %29 = load i32, ptr %add.ptr29.1, align 4, !tbaa !4
+ %arrayidx31.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next86
+ store i32 %29, ptr %arrayidx31.1, align 4, !tbaa !4
+ %indvars.iv.next86.1 = or disjoint i64 %indvars.iv85, 2
+ %30 = trunc nuw nsw i64 %indvars.iv.next86.1 to i32
+ %rem27.2 = urem i32 %30, 10
+ %idx.ext28.2 = zext nneg i32 %rem27.2 to i64
+ %add.ptr29.2 = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28.2
+ %31 = load i32, ptr %add.ptr29.2, align 4, !tbaa !4
+ %arrayidx31.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next86.1
+ store i32 %31, ptr %arrayidx31.2, align 8, !tbaa !4
+ %indvars.iv.next86.2 = or disjoint i64 %indvars.iv85, 3
+ %32 = trunc nuw nsw i64 %indvars.iv.next86.2 to i32
+ %rem27.3 = urem i32 %32, 10
+ %idx.ext28.3 = zext nneg i32 %rem27.3 to i64
+ %add.ptr29.3 = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28.3
+ %33 = load i32, ptr %add.ptr29.3, align 4, !tbaa !4
+ %arrayidx31.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next86.2
+ store i32 %33, ptr %arrayidx31.3, align 4, !tbaa !4
+ %indvars.iv.next86.3 = add nuw nsw i64 %indvars.iv85, 4
+ %niter94.next.3 = add i64 %niter94, 4
+ %niter94.ncmp.3 = icmp eq i64 %niter94.next.3, %unroll_iter93
+ br i1 %niter94.ncmp.3, label %for.cond.cleanup25.loopexit.unr-lcssa, label %for.body26, !llvm.loop !16
+
+if.else35: ; preds = %for.cond.cleanup
+ %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ %34 = load i32, ptr %add.ptr, align 4, !tbaa !4
+ %call37 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %34)
+ %35 = load i32, ptr %len, align 4, !tbaa !4
+ %cmp4072 = icmp sgt i32 %35, 0
+ br i1 %cmp4072, label %for.body42, label %for.cond.cleanup41
+
+for.cond.cleanup41: ; preds = %for.body42, %if.else35
+ call void @func2()
+ unreachable
+
+for.body42: ; preds = %if.else35, %for.body42
+ %indvars.iv79 = phi i64 [ %indvars.iv.next80, %for.body42 ], [ 0, %if.else35 ]
+ %arrayidx44 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv79
+ %36 = load i32, ptr %arrayidx44, align 4, !tbaa !4
+ %call45 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %36)
+ %indvars.iv.next80 = add nuw nsw i64 %indvars.iv79, 1
+ %37 = load i32, ptr %len, align 4, !tbaa !4
+ %38 = sext i32 %37 to i64
+ %cmp40 = icmp slt i64 %indvars.iv.next80, %38
+ br i1 %cmp40, label %for.body42, label %for.cond.cleanup41, !llvm.loop !17
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.21)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.20)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+attributes #5 = { nounwind }
+attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = !{i64 1738}
+!9 = distinct !{!9, !10}
+!10 = !{!"llvm.loop.unroll.disable"}
+!11 = distinct !{!11, !12}
+!12 = !{!"llvm.loop.mustprogress"}
+!13 = !{i64 2419}
+!14 = distinct !{!14, !12}
+!15 = distinct !{!15, !10}
+!16 = distinct !{!16, !12}
+!17 = distinct !{!17, !12}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-00.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-00.ll
new file mode 100644
index 00000000000000..402f3c89ac6714
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-00.ll
@@ -0,0 +1,94 @@
+; -mbackchain option
+; Test output for inline Literal Pool.
+; RUN: clang -mbackchain -o %t %s
+; RUN: %t | FileCheck %s
+; CHECK: value_ptr is 954219
+; CHECK: value_ptr is 954219
+; CHECK: value_ptr is 420420
+
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-00.c'
+source_filename = "builtin-setjmp-longjmp-literal-pool-00.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str = private unnamed_addr constant [17 x i8] c"value_ptr is %d\0A\00", align 2
+
+; Function Attrs: noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #2 {
+entry:
+ %0 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #3, !srcloc !4
+ %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %1, 0
+ %2 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 noundef signext %2)
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+
+if.else: ; preds = %entry
+ %add.ptr2 = getelementptr inbounds i8, ptr %0, i64 40
+ %3 = load i32, ptr %add.ptr2, align 4, !tbaa !5
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 noundef signext %3)
+ ret i32 0
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+
+attributes #0 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+attributes #2 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { nounwind }
+attributes #4 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{i64 751}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll
new file mode 100644
index 00000000000000..3c2fbdc00b599e
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll
@@ -0,0 +1,158 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = 'builtin-setjmp-spills-double-02.c'
+source_filename = "builtin-setjmp-spills-double-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local global double 0.000000e+00, align 8
+ at s = dso_local global double 0.000000e+00, align 8
+ at r = dso_local global double 0.000000e+00, align 8
+ at q = dso_local global double 0.000000e+00, align 8
+ at p = dso_local global double 0.000000e+00, align 8
+ at o = dso_local global double 0.000000e+00, align 8
+ at n = dso_local global double 0.000000e+00, align 8
+ at m = dso_local global double 0.000000e+00, align 8
+ at l = dso_local global double 0.000000e+00, align 8
+ at k = dso_local global double 0.000000e+00, align 8
+ at j = dso_local global double 0.000000e+00, align 8
+ at i = dso_local global double 0.000000e+00, align 8
+ at h = dso_local global double 0.000000e+00, align 8
+ at g = dso_local global double 0.000000e+00, align 8
+ at f = dso_local global double 0.000000e+00, align 8
+ at e = dso_local global double 0.000000e+00, align 8
+ at d = dso_local global double 0.000000e+00, align 8
+ at c = dso_local global double 0.000000e+00, align 8
+ at b = dso_local global double 0.000000e+00, align 8
+ at a = dso_local global double 0.000000e+00, align 8
+ at str = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local double @func() local_unnamed_addr #0 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -344
+; CHECK: std %f8, 336(%r15)
+; CHECK: std %f9, 328(%r15)
+; CHECK: std %f10, 320(%r15)
+; CHECK: std %f11, 312(%r15)
+; CHECK: std %f12, 304(%r15)
+; CHECK: std %f13, 296(%r15)
+; CHECK: std %f14, 288(%r15)
+; CHECK: std %f15, 280(%r15)
+; CHECK: la %r0, 344(%r15)
+; CHECK: stgrl %r0, buf
+; CHECK: stgrl %r15, buf+16
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_2
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %2, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ store double 1.000000e+00, ptr @t, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @s, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @r, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @q, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @p, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @o, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @n, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @m, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @l, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @k, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @j, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @i, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @h, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @g, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @f, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @e, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @d, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @c, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @b, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @a, align 8, !tbaa !4
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ %3 = load double, ptr @a, align 8, !tbaa !4
+ %4 = load double, ptr @b, align 8, !tbaa !4
+ %add = fadd double %3, %4
+ %5 = load double, ptr @c, align 8, !tbaa !4
+ %add1 = fadd double %add, %5
+ %6 = load double, ptr @d, align 8, !tbaa !4
+ %add2 = fadd double %add1, %6
+ %7 = load double, ptr @e, align 8, !tbaa !4
+ %add3 = fadd double %add2, %7
+ %8 = load double, ptr @f, align 8, !tbaa !4
+ %add4 = fadd double %add3, %8
+ %9 = load double, ptr @g, align 8, !tbaa !4
+ %add5 = fadd double %add4, %9
+ %10 = load double, ptr @h, align 8, !tbaa !4
+ %add6 = fadd double %add5, %10
+ %11 = load double, ptr @i, align 8, !tbaa !4
+ %add7 = fadd double %add6, %11
+ %12 = load double, ptr @j, align 8, !tbaa !4
+ %add8 = fadd double %add7, %12
+ %13 = load double, ptr @k, align 8, !tbaa !4
+ %add9 = fadd double %add8, %13
+ %14 = load double, ptr @l, align 8, !tbaa !4
+ %add10 = fadd double %add9, %14
+ %15 = load double, ptr @m, align 8, !tbaa !4
+ %add11 = fadd double %add10, %15
+ %16 = load double, ptr @n, align 8, !tbaa !4
+ %add12 = fadd double %add11, %16
+ %17 = load double, ptr @o, align 8, !tbaa !4
+ %add13 = fadd double %add12, %17
+ %18 = load double, ptr @p, align 8, !tbaa !4
+ %add14 = fadd double %add13, %18
+ %19 = load double, ptr @q, align 8, !tbaa !4
+ %add15 = fadd double %add14, %19
+ %20 = load double, ptr @r, align 8, !tbaa !4
+ %add16 = fadd double %add15, %20
+ %21 = load double, ptr @s, align 8, !tbaa !4
+ %add17 = fadd double %add16, %21
+ %22 = load double, ptr @t, align 8, !tbaa !4
+ %add18 = fadd double %add17, %22
+ ret double %add18
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #1
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #2
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #4
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #5
+
+attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #3 = { nounwind }
+attributes #4 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"double", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll
new file mode 100644
index 00000000000000..0325a1f8fc874c
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll
@@ -0,0 +1,227 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = 'builtin-setjmp-spills-double-03.c'
+source_filename = "builtin-setjmp-spills-double-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local global double 0.000000e+00, align 8
+ at s = dso_local global double 0.000000e+00, align 8
+ at r = dso_local global double 0.000000e+00, align 8
+ at q = dso_local global double 0.000000e+00, align 8
+ at p = dso_local global double 0.000000e+00, align 8
+ at o = dso_local global double 0.000000e+00, align 8
+ at n = dso_local global double 0.000000e+00, align 8
+ at m = dso_local global double 0.000000e+00, align 8
+ at l = dso_local global double 0.000000e+00, align 8
+ at k = dso_local global double 0.000000e+00, align 8
+ at j = dso_local global double 0.000000e+00, align 8
+ at i = dso_local global double 0.000000e+00, align 8
+ at h = dso_local global double 0.000000e+00, align 8
+ at g = dso_local global double 0.000000e+00, align 8
+ at f = dso_local global double 0.000000e+00, align 8
+ at e = dso_local global double 0.000000e+00, align 8
+ at d = dso_local global double 0.000000e+00, align 8
+ at c = dso_local global double 0.000000e+00, align 8
+ at b = dso_local global double 0.000000e+00, align 8
+ at a = dso_local global double 0.000000e+00, align 8
+ at .str.2 = private unnamed_addr constant [9 x i8] c"a = %lf\0A\00", align 2
+ at .str.3 = private unnamed_addr constant [9 x i8] c"b = %lf\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [9 x i8] c"c = %lf\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [9 x i8] c"d = %lf\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [9 x i8] c"e = %lf\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"f = %lf\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [9 x i8] c"g = %lf\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [9 x i8] c"h = %lf\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [9 x i8] c"i = %lf\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [9 x i8] c"j = %lf\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [9 x i8] c"k = %lf\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [9 x i8] c"l = %lf\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [9 x i8] c"m = %lf\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [9 x i8] c"n = %lf\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [9 x i8] c"o = %lf\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [9 x i8] c"p = %lf\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [9 x i8] c"q = %lf\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [9 x i8] c"r = %lf\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [9 x i8] c"s = %lf\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [9 x i8] c"t = %lf\0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.22 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local double @func() local_unnamed_addr #0 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -344
+; CHECK: std %f8, 336(%r15)
+; CHECK: std %f9, 328(%r15)
+; CHECK: std %f10, 320(%r15)
+; CHECK: std %f11, 312(%r15)
+; CHECK: std %f12, 304(%r15)
+; CHECK: std %f13, 296(%r15)
+; CHECK: std %f14, 288(%r15)
+; CHECK: std %f15, 280(%r15)
+; CHECK: la %r0, 344(%r15)
+; CHECK: stgrl %r0, buf
+; CHECK: stgrl %r15, buf+16
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_3
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %2, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ store double 1.000000e+00, ptr @t, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @s, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @r, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @q, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @p, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @o, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @n, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @m, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @l, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @k, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @j, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @i, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @h, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @g, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @f, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @e, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @d, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @c, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @b, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @a, align 8, !tbaa !4
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ br label %if.end
+
+if.else: ; preds = %entry
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ %3 = load double, ptr @a, align 8, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, double noundef %3)
+ %4 = load double, ptr @b, align 8, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, double noundef %4)
+ %5 = load double, ptr @c, align 8, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, double noundef %5)
+ %6 = load double, ptr @d, align 8, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, double noundef %6)
+ %7 = load double, ptr @e, align 8, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, double noundef %7)
+ %8 = load double, ptr @f, align 8, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, double noundef %8)
+ %9 = load double, ptr @g, align 8, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, double noundef %9)
+ %10 = load double, ptr @h, align 8, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, double noundef %10)
+ %11 = load double, ptr @i, align 8, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, double noundef %11)
+ %12 = load double, ptr @j, align 8, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, double noundef %12)
+ %13 = load double, ptr @k, align 8, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, double noundef %13)
+ %14 = load double, ptr @l, align 8, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, double noundef %14)
+ %15 = load double, ptr @m, align 8, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, double noundef %15)
+ %16 = load double, ptr @n, align 8, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, double noundef %16)
+ %17 = load double, ptr @o, align 8, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, double noundef %17)
+ %18 = load double, ptr @p, align 8, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, double noundef %18)
+ %19 = load double, ptr @q, align 8, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, double noundef %19)
+ %20 = load double, ptr @r, align 8, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, double noundef %20)
+ %21 = load double, ptr @s, align 8, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, double noundef %21)
+ %22 = load double, ptr @t, align 8, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, double noundef %22)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %23 = load double, ptr @a, align 8, !tbaa !4
+ %24 = load double, ptr @b, align 8, !tbaa !4
+ %add = fadd double %23, %24
+ %25 = load double, ptr @c, align 8, !tbaa !4
+ %add22 = fadd double %add, %25
+ %26 = load double, ptr @d, align 8, !tbaa !4
+ %add23 = fadd double %add22, %26
+ %27 = load double, ptr @e, align 8, !tbaa !4
+ %add24 = fadd double %add23, %27
+ %28 = load double, ptr @f, align 8, !tbaa !4
+ %add25 = fadd double %add24, %28
+ %29 = load double, ptr @g, align 8, !tbaa !4
+ %add26 = fadd double %add25, %29
+ %30 = load double, ptr @h, align 8, !tbaa !4
+ %add27 = fadd double %add26, %30
+ %31 = load double, ptr @i, align 8, !tbaa !4
+ %add28 = fadd double %add27, %31
+ %32 = load double, ptr @j, align 8, !tbaa !4
+ %add29 = fadd double %add28, %32
+ %33 = load double, ptr @k, align 8, !tbaa !4
+ %add30 = fadd double %add29, %33
+ %34 = load double, ptr @l, align 8, !tbaa !4
+ %add31 = fadd double %add30, %34
+ %35 = load double, ptr @m, align 8, !tbaa !4
+ %add32 = fadd double %add31, %35
+ %36 = load double, ptr @n, align 8, !tbaa !4
+ %add33 = fadd double %add32, %36
+ %37 = load double, ptr @o, align 8, !tbaa !4
+ %add34 = fadd double %add33, %37
+ %38 = load double, ptr @p, align 8, !tbaa !4
+ %add35 = fadd double %add34, %38
+ %39 = load double, ptr @q, align 8, !tbaa !4
+ %add36 = fadd double %add35, %39
+ %40 = load double, ptr @r, align 8, !tbaa !4
+ %add37 = fadd double %add36, %40
+ %41 = load double, ptr @s, align 8, !tbaa !4
+ %add38 = fadd double %add37, %41
+ %42 = load double, ptr @t, align 8, !tbaa !4
+ %add39 = fadd double %add38, %42
+ ret double %add39
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #1
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #2
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #5
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #3 = { nounwind }
+attributes #4 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"double", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-01.ll
new file mode 100644
index 00000000000000..4d56a9dd19bbdf
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-01.ll
@@ -0,0 +1,246 @@
+; -mbackchain option
+; Inducing double register pressure.
+; Test output of setjmp/longjmp with 20 global double variable
+; sum(regsiter pressure).
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-spills-double-01.c'
+source_filename = "builtin-setjmp-spills-double-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at s = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at r = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at q = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at p = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at o = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at n = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at m = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at l = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at k = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at j = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at i = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at h = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at g = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at f = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at e = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at d = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at c = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at b = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at a = dso_local local_unnamed_addr global double 0.000000e+00, align 8
+ at .str.3 = private unnamed_addr constant [9 x i8] c"a = %lf\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [9 x i8] c"b = %lf\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [9 x i8] c"c = %lf\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [9 x i8] c"d = %lf\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"e = %lf\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [9 x i8] c"f = %lf\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [9 x i8] c"g = %lf\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [9 x i8] c"h = %lf\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [9 x i8] c"i = %lf\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [9 x i8] c"j = %lf\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [9 x i8] c"k = %lf\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [9 x i8] c"l = %lf\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [9 x i8] c"m = %lf\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [9 x i8] c"n = %lf\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [9 x i8] c"o = %lf\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [9 x i8] c"p = %lf\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [9 x i8] c"q = %lf\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [9 x i8] c"r = %lf\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [9 x i8] c"s = %lf\0A\00", align 2
+ at .str.22 = private unnamed_addr constant [9 x i8] c"t = %lf\0A\00", align 2
+ at .str.23 = private unnamed_addr constant [12 x i8] c"val is %lf\0A\00", align 2
+ at str = private unnamed_addr constant [8 x i8] c"In func\00", align 1
+ at str.24 = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.25 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func1() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind
+define dso_local double @func() local_unnamed_addr #3 {
+entry:
+; CHECK: First time through, all variables are 1
+; CHECK: In func
+; CHECK: Second time through, checking variables:
+; CHECK: a = 1.000000
+; CHECK: b = 1.000000
+; CHECK: c = 1.000000
+; CHECK: d = 1.000000
+; CHECK: e = 1.000000
+; CHECK: f = 1.000000
+; CHECK: g = 1.000000
+; CHECK: h = 1.000000
+; CHECK: i = 1.000000
+; CHECK: j = 1.000000
+; CHECK: k = 1.000000
+; CHECK: l = 1.000000
+; CHECK: m = 1.000000
+; CHECK: n = 1.000000
+; CHECK: o = 1.000000
+; CHECK: p = 1.000000
+; CHECK: q = 1.000000
+; CHECK: r = 1.000000
+; CHECK: s = 1.000000
+; CHECK: t = 1.000000
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ store double 1.000000e+00, ptr @t, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @s, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @r, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @q, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @p, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @o, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @n, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @m, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @l, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @k, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @j, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @i, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @h, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @g, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @f, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @e, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @d, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @c, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @b, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @a, align 8, !tbaa !4
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.25)
+ tail call void @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.24)
+ %1 = load double, ptr @a, align 8, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, double noundef %1)
+ %2 = load double, ptr @b, align 8, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, double noundef %2)
+ %3 = load double, ptr @c, align 8, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, double noundef %3)
+ %4 = load double, ptr @d, align 8, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, double noundef %4)
+ %5 = load double, ptr @e, align 8, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, double noundef %5)
+ %6 = load double, ptr @f, align 8, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, double noundef %6)
+ %7 = load double, ptr @g, align 8, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, double noundef %7)
+ %8 = load double, ptr @h, align 8, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, double noundef %8)
+ %9 = load double, ptr @i, align 8, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, double noundef %9)
+ %10 = load double, ptr @j, align 8, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, double noundef %10)
+ %11 = load double, ptr @k, align 8, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, double noundef %11)
+ %12 = load double, ptr @l, align 8, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, double noundef %12)
+ %13 = load double, ptr @m, align 8, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, double noundef %13)
+ %14 = load double, ptr @n, align 8, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, double noundef %14)
+ %15 = load double, ptr @o, align 8, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, double noundef %15)
+ %16 = load double, ptr @p, align 8, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, double noundef %16)
+ %17 = load double, ptr @q, align 8, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, double noundef %17)
+ %18 = load double, ptr @r, align 8, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, double noundef %18)
+ %19 = load double, ptr @s, align 8, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, double noundef %19)
+ %20 = load double, ptr @t, align 8, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.22, double noundef %20)
+ %21 = load double, ptr @a, align 8, !tbaa !4
+ %22 = load double, ptr @b, align 8, !tbaa !4
+ %add = fadd double %21, %22
+ %23 = load double, ptr @c, align 8, !tbaa !4
+ %add22 = fadd double %add, %23
+ %24 = load double, ptr @d, align 8, !tbaa !4
+ %add23 = fadd double %add22, %24
+ %25 = load double, ptr @e, align 8, !tbaa !4
+ %add24 = fadd double %add23, %25
+ %26 = load double, ptr @f, align 8, !tbaa !4
+ %add25 = fadd double %add24, %26
+ %27 = load double, ptr @g, align 8, !tbaa !4
+ %add26 = fadd double %add25, %27
+ %28 = load double, ptr @h, align 8, !tbaa !4
+ %add27 = fadd double %add26, %28
+ %29 = load double, ptr @i, align 8, !tbaa !4
+ %add28 = fadd double %add27, %29
+ %30 = load double, ptr @j, align 8, !tbaa !4
+ %add29 = fadd double %add28, %30
+ %31 = load double, ptr @k, align 8, !tbaa !4
+ %add30 = fadd double %add29, %31
+ %32 = load double, ptr @l, align 8, !tbaa !4
+ %add31 = fadd double %add30, %32
+ %33 = load double, ptr @m, align 8, !tbaa !4
+ %add32 = fadd double %add31, %33
+ %34 = load double, ptr @n, align 8, !tbaa !4
+ %add33 = fadd double %add32, %34
+ %35 = load double, ptr @o, align 8, !tbaa !4
+ %add34 = fadd double %add33, %35
+ %36 = load double, ptr @p, align 8, !tbaa !4
+ %add35 = fadd double %add34, %36
+ %37 = load double, ptr @q, align 8, !tbaa !4
+ %add36 = fadd double %add35, %37
+ %38 = load double, ptr @r, align 8, !tbaa !4
+ %add37 = fadd double %add36, %38
+ %39 = load double, ptr @s, align 8, !tbaa !4
+ %add38 = fadd double %add37, %39
+ %40 = load double, ptr @t, align 8, !tbaa !4
+ %add39 = fadd double %add38, %40
+ ret double %add39
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+; CHECK: val is 20.000000
+ %call = tail call double @func()
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.23, double noundef %call)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"double", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-02.ll
new file mode 100644
index 00000000000000..784a1e3583e7eb
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-02.ll
@@ -0,0 +1,153 @@
+; -mbackchain option.
+; Simulate register pressure around setjmp call for double precision arguments.
+; Test assembly of funtion call foo in func() in setjmp if and else part.
+; extern foo has 20 argument pointer to double precision.
+; Test setjmp store jmp_buf.
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
+; RUN: llc < %s | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-spills-double-02.c'
+source_filename = "builtin-setjmp-spills-double-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local global double 0.000000e+00, align 8
+ at s = dso_local global double 0.000000e+00, align 8
+ at r = dso_local global double 0.000000e+00, align 8
+ at q = dso_local global double 0.000000e+00, align 8
+ at p = dso_local global double 0.000000e+00, align 8
+ at o = dso_local global double 0.000000e+00, align 8
+ at n = dso_local global double 0.000000e+00, align 8
+ at m = dso_local global double 0.000000e+00, align 8
+ at l = dso_local global double 0.000000e+00, align 8
+ at k = dso_local global double 0.000000e+00, align 8
+ at j = dso_local global double 0.000000e+00, align 8
+ at i = dso_local global double 0.000000e+00, align 8
+ at h = dso_local global double 0.000000e+00, align 8
+ at g = dso_local global double 0.000000e+00, align 8
+ at f = dso_local global double 0.000000e+00, align 8
+ at e = dso_local global double 0.000000e+00, align 8
+ at d = dso_local global double 0.000000e+00, align 8
+ at c = dso_local global double 0.000000e+00, align 8
+ at b = dso_local global double 0.000000e+00, align 8
+ at a = dso_local global double 0.000000e+00, align 8
+ at str = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local double @func() local_unnamed_addr #0 {
+entry:
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -344
+; CHECK: std %f8, 336(%r15)
+; CHECK: std %f9, 328(%r15)
+; CHECK: std %f10, 320(%r15)
+; CHECK: std %f11, 312(%r15)
+; CHECK: std %f12, 304(%r15)
+; CHECK: std %f13, 296(%r15)
+; CHECK: std %f14, 288(%r15)
+; CHECK: std %f15, 280(%r15)
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_2
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ store double 1.000000e+00, ptr @t, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @s, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @r, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @q, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @p, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @o, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @n, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @m, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @l, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @k, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @j, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @i, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @h, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @g, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @f, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @e, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @d, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @c, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @b, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @a, align 8, !tbaa !4
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
+ %1 = load double, ptr @a, align 8, !tbaa !4
+ %2 = load double, ptr @b, align 8, !tbaa !4
+ %add = fadd double %1, %2
+ %3 = load double, ptr @c, align 8, !tbaa !4
+ %add1 = fadd double %add, %3
+ %4 = load double, ptr @d, align 8, !tbaa !4
+ %add2 = fadd double %add1, %4
+ %5 = load double, ptr @e, align 8, !tbaa !4
+ %add3 = fadd double %add2, %5
+ %6 = load double, ptr @f, align 8, !tbaa !4
+ %add4 = fadd double %add3, %6
+ %7 = load double, ptr @g, align 8, !tbaa !4
+ %add5 = fadd double %add4, %7
+ %8 = load double, ptr @h, align 8, !tbaa !4
+ %add6 = fadd double %add5, %8
+ %9 = load double, ptr @i, align 8, !tbaa !4
+ %add7 = fadd double %add6, %9
+ %10 = load double, ptr @j, align 8, !tbaa !4
+ %add8 = fadd double %add7, %10
+ %11 = load double, ptr @k, align 8, !tbaa !4
+ %add9 = fadd double %add8, %11
+ %12 = load double, ptr @l, align 8, !tbaa !4
+ %add10 = fadd double %add9, %12
+ %13 = load double, ptr @m, align 8, !tbaa !4
+ %add11 = fadd double %add10, %13
+ %14 = load double, ptr @n, align 8, !tbaa !4
+ %add12 = fadd double %add11, %14
+ %15 = load double, ptr @o, align 8, !tbaa !4
+ %add13 = fadd double %add12, %15
+ %16 = load double, ptr @p, align 8, !tbaa !4
+ %add14 = fadd double %add13, %16
+ %17 = load double, ptr @q, align 8, !tbaa !4
+ %add15 = fadd double %add14, %17
+ %18 = load double, ptr @r, align 8, !tbaa !4
+ %add16 = fadd double %add15, %18
+ %19 = load double, ptr @s, align 8, !tbaa !4
+ %add17 = fadd double %add16, %19
+ %20 = load double, ptr @t, align 8, !tbaa !4
+ %add18 = fadd double %add17, %20
+ ret double %add18
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
+
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #2
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #3
+
+attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nounwind }
+attributes #2 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"double", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-03.ll
new file mode 100644
index 00000000000000..78a6cc784847cc
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-03.ll
@@ -0,0 +1,225 @@
+; -mbackchain option.
+; Simulate register pressure around setjmp call for double precision
+; arguments and return sum of 20 vaiables. It also prints the variables.
+; Test assembly of funtion call foo in func() in setjmp if and else part.
+; extern foo has 20 argument pointer to double precision.
+; Test setjmp store jmp_buf.
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
+; RUN: llc < %s | FileCheck %s
+
+
+; ModuleID = 'builtin-setjmp-spills-double-03.c'
+source_filename = "builtin-setjmp-spills-double-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local global double 0.000000e+00, align 8
+ at s = dso_local global double 0.000000e+00, align 8
+ at r = dso_local global double 0.000000e+00, align 8
+ at q = dso_local global double 0.000000e+00, align 8
+ at p = dso_local global double 0.000000e+00, align 8
+ at o = dso_local global double 0.000000e+00, align 8
+ at n = dso_local global double 0.000000e+00, align 8
+ at m = dso_local global double 0.000000e+00, align 8
+ at l = dso_local global double 0.000000e+00, align 8
+ at k = dso_local global double 0.000000e+00, align 8
+ at j = dso_local global double 0.000000e+00, align 8
+ at i = dso_local global double 0.000000e+00, align 8
+ at h = dso_local global double 0.000000e+00, align 8
+ at g = dso_local global double 0.000000e+00, align 8
+ at f = dso_local global double 0.000000e+00, align 8
+ at e = dso_local global double 0.000000e+00, align 8
+ at d = dso_local global double 0.000000e+00, align 8
+ at c = dso_local global double 0.000000e+00, align 8
+ at b = dso_local global double 0.000000e+00, align 8
+ at a = dso_local global double 0.000000e+00, align 8
+ at .str.2 = private unnamed_addr constant [9 x i8] c"a = %lf\0A\00", align 2
+ at .str.3 = private unnamed_addr constant [9 x i8] c"b = %lf\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [9 x i8] c"c = %lf\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [9 x i8] c"d = %lf\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [9 x i8] c"e = %lf\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"f = %lf\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [9 x i8] c"g = %lf\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [9 x i8] c"h = %lf\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [9 x i8] c"i = %lf\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [9 x i8] c"j = %lf\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [9 x i8] c"k = %lf\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [9 x i8] c"l = %lf\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [9 x i8] c"m = %lf\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [9 x i8] c"n = %lf\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [9 x i8] c"o = %lf\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [9 x i8] c"p = %lf\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [9 x i8] c"q = %lf\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [9 x i8] c"r = %lf\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [9 x i8] c"s = %lf\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [9 x i8] c"t = %lf\0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.22 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local double @func() local_unnamed_addr #0 {
+entry:
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -344
+; CHECK: std %f8, 336(%r15)
+; CHECK: std %f9, 328(%r15)
+; CHECK: std %f10, 320(%r15)
+; CHECK: std %f11, 312(%r15)
+; CHECK: std %f12, 304(%r15)
+; CHECK: std %f13, 296(%r15)
+; CHECK: std %f14, 288(%r15)
+; CHECK: std %f15, 280(%r15)
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_3
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ store double 1.000000e+00, ptr @t, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @s, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @r, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @q, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @p, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @o, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @n, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @m, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @l, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @k, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @j, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @i, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @h, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @g, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @f, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @e, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @d, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @c, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @b, align 8, !tbaa !4
+ store double 1.000000e+00, ptr @a, align 8, !tbaa !4
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
+ br label %if.end
+
+if.else: ; preds = %entry
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ %1 = load double, ptr @a, align 8, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, double noundef %1)
+ %2 = load double, ptr @b, align 8, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, double noundef %2)
+ %3 = load double, ptr @c, align 8, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, double noundef %3)
+ %4 = load double, ptr @d, align 8, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, double noundef %4)
+ %5 = load double, ptr @e, align 8, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, double noundef %5)
+ %6 = load double, ptr @f, align 8, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, double noundef %6)
+ %7 = load double, ptr @g, align 8, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, double noundef %7)
+ %8 = load double, ptr @h, align 8, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, double noundef %8)
+ %9 = load double, ptr @i, align 8, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, double noundef %9)
+ %10 = load double, ptr @j, align 8, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, double noundef %10)
+ %11 = load double, ptr @k, align 8, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, double noundef %11)
+ %12 = load double, ptr @l, align 8, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, double noundef %12)
+ %13 = load double, ptr @m, align 8, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, double noundef %13)
+ %14 = load double, ptr @n, align 8, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, double noundef %14)
+ %15 = load double, ptr @o, align 8, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, double noundef %15)
+ %16 = load double, ptr @p, align 8, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, double noundef %16)
+ %17 = load double, ptr @q, align 8, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, double noundef %17)
+ %18 = load double, ptr @r, align 8, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, double noundef %18)
+ %19 = load double, ptr @s, align 8, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, double noundef %19)
+ %20 = load double, ptr @t, align 8, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, double noundef %20)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %21 = load double, ptr @a, align 8, !tbaa !4
+ %22 = load double, ptr @b, align 8, !tbaa !4
+ %add = fadd double %21, %22
+ %23 = load double, ptr @c, align 8, !tbaa !4
+ %add22 = fadd double %add, %23
+ %24 = load double, ptr @d, align 8, !tbaa !4
+ %add23 = fadd double %add22, %24
+ %25 = load double, ptr @e, align 8, !tbaa !4
+ %add24 = fadd double %add23, %25
+ %26 = load double, ptr @f, align 8, !tbaa !4
+ %add25 = fadd double %add24, %26
+ %27 = load double, ptr @g, align 8, !tbaa !4
+ %add26 = fadd double %add25, %27
+ %28 = load double, ptr @h, align 8, !tbaa !4
+ %add27 = fadd double %add26, %28
+ %29 = load double, ptr @i, align 8, !tbaa !4
+ %add28 = fadd double %add27, %29
+ %30 = load double, ptr @j, align 8, !tbaa !4
+ %add29 = fadd double %add28, %30
+ %31 = load double, ptr @k, align 8, !tbaa !4
+ %add30 = fadd double %add29, %31
+ %32 = load double, ptr @l, align 8, !tbaa !4
+ %add31 = fadd double %add30, %32
+ %33 = load double, ptr @m, align 8, !tbaa !4
+ %add32 = fadd double %add31, %33
+ %34 = load double, ptr @n, align 8, !tbaa !4
+ %add33 = fadd double %add32, %34
+ %35 = load double, ptr @o, align 8, !tbaa !4
+ %add34 = fadd double %add33, %35
+ %36 = load double, ptr @p, align 8, !tbaa !4
+ %add35 = fadd double %add34, %36
+ %37 = load double, ptr @q, align 8, !tbaa !4
+ %add36 = fadd double %add35, %37
+ %38 = load double, ptr @r, align 8, !tbaa !4
+ %add37 = fadd double %add36, %38
+ %39 = load double, ptr @s, align 8, !tbaa !4
+ %add38 = fadd double %add37, %39
+ %40 = load double, ptr @t, align 8, !tbaa !4
+ %add39 = fadd double %add38, %40
+ ret double %add39
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #2
+
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #3
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #4
+
+attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nounwind }
+attributes #2 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"double", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll
new file mode 100644
index 00000000000000..40a4794db39da0
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll
@@ -0,0 +1,157 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = 'builtin-setjmp-spills-int-02.c'
+source_filename = "builtin-setjmp-spills-int-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local global i32 0, align 4
+ at s = dso_local global i32 0, align 4
+ at r = dso_local global i32 0, align 4
+ at q = dso_local global i32 0, align 4
+ at p = dso_local global i32 0, align 4
+ at o = dso_local global i32 0, align 4
+ at n = dso_local global i32 0, align 4
+ at m = dso_local global i32 0, align 4
+ at l = dso_local global i32 0, align 4
+ at k = dso_local global i32 0, align 4
+ at j = dso_local global i32 0, align 4
+ at i = dso_local global i32 0, align 4
+ at h = dso_local global i32 0, align 4
+ at g = dso_local global i32 0, align 4
+ at f = dso_local global i32 0, align 4
+ at e = dso_local global i32 0, align 4
+ at d = dso_local global i32 0, align 4
+ at c = dso_local global i32 0, align 4
+ at b = dso_local global i32 0, align 4
+ at a = dso_local global i32 0, align 4
+ at str = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local signext i32 @func() local_unnamed_addr #0 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -344
+; CHECK: std %f8, 336(%r15)
+; CHECK: std %f9, 328(%r15)
+; CHECK: std %f10, 320(%r15)
+; CHECK: std %f11, 312(%r15)
+; CHECK: std %f12, 304(%r15)
+; CHECK: std %f13, 296(%r15)
+; CHECK: std %f14, 288(%r15)
+; CHECK: std %f15, 280(%r15)
+; CHECK: la %r0, 344(%r15)
+; CHECK: stgrl %r0, buf
+; CHECK: stgrl %r15, buf+16
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_2
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %2, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ store i32 1, ptr @t, align 4, !tbaa !4
+ store i32 1, ptr @s, align 4, !tbaa !4
+ store i32 1, ptr @r, align 4, !tbaa !4
+ store i32 1, ptr @q, align 4, !tbaa !4
+ store i32 1, ptr @p, align 4, !tbaa !4
+ store i32 1, ptr @o, align 4, !tbaa !4
+ store i32 1, ptr @n, align 4, !tbaa !4
+ store i32 1, ptr @m, align 4, !tbaa !4
+ store i32 1, ptr @l, align 4, !tbaa !4
+ store i32 1, ptr @k, align 4, !tbaa !4
+ store i32 1, ptr @j, align 4, !tbaa !4
+ store i32 1, ptr @i, align 4, !tbaa !4
+ store i32 1, ptr @h, align 4, !tbaa !4
+ store i32 1, ptr @g, align 4, !tbaa !4
+ store i32 1, ptr @f, align 4, !tbaa !4
+ store i32 1, ptr @e, align 4, !tbaa !4
+ store i32 1, ptr @d, align 4, !tbaa !4
+ store i32 1, ptr @c, align 4, !tbaa !4
+ store i32 1, ptr @b, align 4, !tbaa !4
+ store i32 1, ptr @a, align 4, !tbaa !4
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ %3 = load i32, ptr @a, align 4, !tbaa !4
+ %4 = load i32, ptr @b, align 4, !tbaa !4
+ %add = add nsw i32 %4, %3
+ %5 = load i32, ptr @c, align 4, !tbaa !4
+ %add1 = add nsw i32 %add, %5
+ %6 = load i32, ptr @d, align 4, !tbaa !4
+ %add2 = add nsw i32 %add1, %6
+ %7 = load i32, ptr @e, align 4, !tbaa !4
+ %add3 = add nsw i32 %add2, %7
+ %8 = load i32, ptr @f, align 4, !tbaa !4
+ %add4 = add nsw i32 %add3, %8
+ %9 = load i32, ptr @g, align 4, !tbaa !4
+ %add5 = add nsw i32 %add4, %9
+ %10 = load i32, ptr @h, align 4, !tbaa !4
+ %add6 = add nsw i32 %add5, %10
+ %11 = load i32, ptr @i, align 4, !tbaa !4
+ %add7 = add nsw i32 %add6, %11
+ %12 = load i32, ptr @j, align 4, !tbaa !4
+ %add8 = add nsw i32 %add7, %12
+ %13 = load i32, ptr @k, align 4, !tbaa !4
+ %add9 = add nsw i32 %add8, %13
+ %14 = load i32, ptr @l, align 4, !tbaa !4
+ %add10 = add nsw i32 %add9, %14
+ %15 = load i32, ptr @m, align 4, !tbaa !4
+ %add11 = add nsw i32 %add10, %15
+ %16 = load i32, ptr @n, align 4, !tbaa !4
+ %add12 = add nsw i32 %add11, %16
+ %17 = load i32, ptr @o, align 4, !tbaa !4
+ %add13 = add nsw i32 %add12, %17
+ %18 = load i32, ptr @p, align 4, !tbaa !4
+ %add14 = add nsw i32 %add13, %18
+ %19 = load i32, ptr @q, align 4, !tbaa !4
+ %add15 = add nsw i32 %add14, %19
+ %20 = load i32, ptr @r, align 4, !tbaa !4
+ %add16 = add nsw i32 %add15, %20
+ %21 = load i32, ptr @s, align 4, !tbaa !4
+ %add17 = add nsw i32 %add16, %21
+ %22 = load i32, ptr @t, align 4, !tbaa !4
+ %add18 = add nsw i32 %add17, %22
+ ret i32 %add18
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #1
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #2
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #4
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #5
+
+attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #3 = { nounwind }
+attributes #4 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll
new file mode 100644
index 00000000000000..f0ae742c6e45d5
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll
@@ -0,0 +1,227 @@
+; RUN: llc < %s | FileCheck %s
+; ModuleID = 'builtin-setjmp-spills-int-03.c'
+source_filename = "builtin-setjmp-spills-int-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local global i32 0, align 4
+ at s = dso_local global i32 0, align 4
+ at r = dso_local global i32 0, align 4
+ at q = dso_local global i32 0, align 4
+ at p = dso_local global i32 0, align 4
+ at o = dso_local global i32 0, align 4
+ at n = dso_local global i32 0, align 4
+ at m = dso_local global i32 0, align 4
+ at l = dso_local global i32 0, align 4
+ at k = dso_local global i32 0, align 4
+ at j = dso_local global i32 0, align 4
+ at i = dso_local global i32 0, align 4
+ at h = dso_local global i32 0, align 4
+ at g = dso_local global i32 0, align 4
+ at f = dso_local global i32 0, align 4
+ at e = dso_local global i32 0, align 4
+ at d = dso_local global i32 0, align 4
+ at c = dso_local global i32 0, align 4
+ at b = dso_local global i32 0, align 4
+ at a = dso_local global i32 0, align 4
+ at .str.2 = private unnamed_addr constant [8 x i8] c"a = %d\0A\00", align 2
+ at .str.3 = private unnamed_addr constant [8 x i8] c"b = %d\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [8 x i8] c"c = %d\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [8 x i8] c"d = %d\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [8 x i8] c"e = %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [8 x i8] c"f = %d\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [8 x i8] c"g = %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [8 x i8] c"h = %d\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [8 x i8] c"j = %d\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [8 x i8] c"k = %d\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [8 x i8] c"l = %d\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [8 x i8] c"m = %d\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [8 x i8] c"n = %d\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [8 x i8] c"o = %d\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [8 x i8] c"p = %d\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [8 x i8] c"q = %d\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [8 x i8] c"r = %d\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [8 x i8] c"s = %d\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [8 x i8] c"t = %d\0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.22 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local signext i32 @func() local_unnamed_addr #0 {
+entry:
+ %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
+ store ptr %0, ptr @buf, align 8
+ %1 = tail call ptr @llvm.stacksave.p0()
+ store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -344
+; CHECK: std %f8, 336(%r15)
+; CHECK: std %f9, 328(%r15)
+; CHECK: std %f10, 320(%r15)
+; CHECK: std %f11, 312(%r15)
+; CHECK: std %f12, 304(%r15)
+; CHECK: std %f13, 296(%r15)
+; CHECK: std %f14, 288(%r15)
+; CHECK: std %f15, 280(%r15)
+; CHECK: la %r0, 344(%r15)
+; CHECK: stgrl %r0, buf
+; CHECK: stgrl %r15, buf+16
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_3
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %2, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ store i32 1, ptr @t, align 4, !tbaa !4
+ store i32 1, ptr @s, align 4, !tbaa !4
+ store i32 1, ptr @r, align 4, !tbaa !4
+ store i32 1, ptr @q, align 4, !tbaa !4
+ store i32 1, ptr @p, align 4, !tbaa !4
+ store i32 1, ptr @o, align 4, !tbaa !4
+ store i32 1, ptr @n, align 4, !tbaa !4
+ store i32 1, ptr @m, align 4, !tbaa !4
+ store i32 1, ptr @l, align 4, !tbaa !4
+ store i32 1, ptr @k, align 4, !tbaa !4
+ store i32 1, ptr @j, align 4, !tbaa !4
+ store i32 1, ptr @i, align 4, !tbaa !4
+ store i32 1, ptr @h, align 4, !tbaa !4
+ store i32 1, ptr @g, align 4, !tbaa !4
+ store i32 1, ptr @f, align 4, !tbaa !4
+ store i32 1, ptr @e, align 4, !tbaa !4
+ store i32 1, ptr @d, align 4, !tbaa !4
+ store i32 1, ptr @c, align 4, !tbaa !4
+ store i32 1, ptr @b, align 4, !tbaa !4
+ store i32 1, ptr @a, align 4, !tbaa !4
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ br label %if.end
+
+if.else: ; preds = %entry
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ %3 = load i32, ptr @a, align 4, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %3)
+ %4 = load i32, ptr @b, align 4, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %4)
+ %5 = load i32, ptr @c, align 4, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %5)
+ %6 = load i32, ptr @d, align 4, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, i32 noundef signext %6)
+ %7 = load i32, ptr @e, align 4, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %7)
+ %8 = load i32, ptr @f, align 4, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %8)
+ %9 = load i32, ptr @g, align 4, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %9)
+ %10 = load i32, ptr @h, align 4, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %10)
+ %11 = load i32, ptr @i, align 4, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, i32 noundef signext %11)
+ %12 = load i32, ptr @j, align 4, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %12)
+ %13 = load i32, ptr @k, align 4, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, i32 noundef signext %13)
+ %14 = load i32, ptr @l, align 4, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %14)
+ %15 = load i32, ptr @m, align 4, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, i32 noundef signext %15)
+ %16 = load i32, ptr @n, align 4, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, i32 noundef signext %16)
+ %17 = load i32, ptr @o, align 4, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, i32 noundef signext %17)
+ %18 = load i32, ptr @p, align 4, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, i32 noundef signext %18)
+ %19 = load i32, ptr @q, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, i32 noundef signext %19)
+ %20 = load i32, ptr @r, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, i32 noundef signext %20)
+ %21 = load i32, ptr @s, align 4, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, i32 noundef signext %21)
+ %22 = load i32, ptr @t, align 4, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, i32 noundef signext %22)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %23 = load i32, ptr @a, align 4, !tbaa !4
+ %24 = load i32, ptr @b, align 4, !tbaa !4
+ %add = add nsw i32 %24, %23
+ %25 = load i32, ptr @c, align 4, !tbaa !4
+ %add22 = add nsw i32 %add, %25
+ %26 = load i32, ptr @d, align 4, !tbaa !4
+ %add23 = add nsw i32 %add22, %26
+ %27 = load i32, ptr @e, align 4, !tbaa !4
+ %add24 = add nsw i32 %add23, %27
+ %28 = load i32, ptr @f, align 4, !tbaa !4
+ %add25 = add nsw i32 %add24, %28
+ %29 = load i32, ptr @g, align 4, !tbaa !4
+ %add26 = add nsw i32 %add25, %29
+ %30 = load i32, ptr @h, align 4, !tbaa !4
+ %add27 = add nsw i32 %add26, %30
+ %31 = load i32, ptr @i, align 4, !tbaa !4
+ %add28 = add nsw i32 %add27, %31
+ %32 = load i32, ptr @j, align 4, !tbaa !4
+ %add29 = add nsw i32 %add28, %32
+ %33 = load i32, ptr @k, align 4, !tbaa !4
+ %add30 = add nsw i32 %add29, %33
+ %34 = load i32, ptr @l, align 4, !tbaa !4
+ %add31 = add nsw i32 %add30, %34
+ %35 = load i32, ptr @m, align 4, !tbaa !4
+ %add32 = add nsw i32 %add31, %35
+ %36 = load i32, ptr @n, align 4, !tbaa !4
+ %add33 = add nsw i32 %add32, %36
+ %37 = load i32, ptr @o, align 4, !tbaa !4
+ %add34 = add nsw i32 %add33, %37
+ %38 = load i32, ptr @p, align 4, !tbaa !4
+ %add35 = add nsw i32 %add34, %38
+ %39 = load i32, ptr @q, align 4, !tbaa !4
+ %add36 = add nsw i32 %add35, %39
+ %40 = load i32, ptr @r, align 4, !tbaa !4
+ %add37 = add nsw i32 %add36, %40
+ %41 = load i32, ptr @s, align 4, !tbaa !4
+ %add38 = add nsw i32 %add37, %41
+ %42 = load i32, ptr @t, align 4, !tbaa !4
+ %add39 = add nsw i32 %add38, %42
+ ret i32 %add39
+}
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
+declare ptr @llvm.frameaddress.p0(i32 immarg) #1
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
+declare ptr @llvm.stacksave.p0() #2
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #5
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
+attributes #3 = { nounwind }
+attributes #4 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-01.ll
new file mode 100644
index 00000000000000..0a51c45173e243
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-01.ll
@@ -0,0 +1,241 @@
+; Test output of setjmp/longjmp with 20 global variable sum(regsiter pressure).
+; RUN: clang -mbackchain -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-spills-int-01.c'
+source_filename = "builtin-setjmp-spills-int-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local local_unnamed_addr global i32 0, align 4
+ at s = dso_local local_unnamed_addr global i32 0, align 4
+ at r = dso_local local_unnamed_addr global i32 0, align 4
+ at q = dso_local local_unnamed_addr global i32 0, align 4
+ at p = dso_local local_unnamed_addr global i32 0, align 4
+ at o = dso_local local_unnamed_addr global i32 0, align 4
+ at n = dso_local local_unnamed_addr global i32 0, align 4
+ at m = dso_local local_unnamed_addr global i32 0, align 4
+ at l = dso_local local_unnamed_addr global i32 0, align 4
+ at k = dso_local local_unnamed_addr global i32 0, align 4
+ at j = dso_local local_unnamed_addr global i32 0, align 4
+ at i = dso_local local_unnamed_addr global i32 0, align 4
+ at h = dso_local local_unnamed_addr global i32 0, align 4
+ at g = dso_local local_unnamed_addr global i32 0, align 4
+ at f = dso_local local_unnamed_addr global i32 0, align 4
+ at e = dso_local local_unnamed_addr global i32 0, align 4
+ at d = dso_local local_unnamed_addr global i32 0, align 4
+ at c = dso_local local_unnamed_addr global i32 0, align 4
+ at b = dso_local local_unnamed_addr global i32 0, align 4
+ at a = dso_local local_unnamed_addr global i32 0, align 4
+ at .str.3 = private unnamed_addr constant [8 x i8] c"a = %d\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [8 x i8] c"b = %d\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [8 x i8] c"c = %d\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [8 x i8] c"d = %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [8 x i8] c"e = %d\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [8 x i8] c"f = %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [8 x i8] c"g = %d\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [8 x i8] c"h = %d\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [8 x i8] c"j = %d\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [8 x i8] c"k = %d\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [8 x i8] c"l = %d\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [8 x i8] c"m = %d\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [8 x i8] c"n = %d\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [8 x i8] c"o = %d\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [8 x i8] c"p = %d\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [8 x i8] c"q = %d\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [8 x i8] c"r = %d\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [8 x i8] c"s = %d\0A\00", align 2
+ at .str.22 = private unnamed_addr constant [8 x i8] c"t = %d\0A\00", align 2
+ at .str.23 = private unnamed_addr constant [11 x i8] c"val is %d\0A\00", align 2
+ at str = private unnamed_addr constant [8 x i8] c"In func\00", align 1
+ at str.24 = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.25 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func1() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind
+define dso_local signext i32 @func() local_unnamed_addr #3 {
+entry:
+; CHECK: Second time through, checking variables:
+; CHECK: a = 1
+; CHECK: b = 1
+; CHECK: c = 1
+; CHECK: d = 1
+; CHECK: e = 1
+; CHECK: f = 1
+; CHECK: g = 1
+; CHECK: h = 1
+; CHECK: i = 1
+; CHECK: j = 1
+; CHECK: k = 1
+; CHECK: l = 1
+; CHECK: m = 1
+; CHECK: n = 1
+; CHECK: o = 1
+; CHECK: p = 1
+; CHECK: q = 1
+; CHECK: r = 1
+; CHECK: s = 1
+; CHECK: t = 1
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ store i32 1, ptr @t, align 4, !tbaa !4
+ store i32 1, ptr @s, align 4, !tbaa !4
+ store i32 1, ptr @r, align 4, !tbaa !4
+ store i32 1, ptr @q, align 4, !tbaa !4
+ store i32 1, ptr @p, align 4, !tbaa !4
+ store i32 1, ptr @o, align 4, !tbaa !4
+ store i32 1, ptr @n, align 4, !tbaa !4
+ store i32 1, ptr @m, align 4, !tbaa !4
+ store i32 1, ptr @l, align 4, !tbaa !4
+ store i32 1, ptr @k, align 4, !tbaa !4
+ store i32 1, ptr @j, align 4, !tbaa !4
+ store i32 1, ptr @i, align 4, !tbaa !4
+ store i32 1, ptr @h, align 4, !tbaa !4
+ store i32 1, ptr @g, align 4, !tbaa !4
+ store i32 1, ptr @f, align 4, !tbaa !4
+ store i32 1, ptr @e, align 4, !tbaa !4
+ store i32 1, ptr @d, align 4, !tbaa !4
+ store i32 1, ptr @c, align 4, !tbaa !4
+ store i32 1, ptr @b, align 4, !tbaa !4
+ store i32 1, ptr @a, align 4, !tbaa !4
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.25)
+ tail call void @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.24)
+ %1 = load i32, ptr @a, align 4, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %1)
+ %2 = load i32, ptr @b, align 4, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %2)
+ %3 = load i32, ptr @c, align 4, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, i32 noundef signext %3)
+ %4 = load i32, ptr @d, align 4, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %4)
+ %5 = load i32, ptr @e, align 4, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %5)
+ %6 = load i32, ptr @f, align 4, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %6)
+ %7 = load i32, ptr @g, align 4, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %7)
+ %8 = load i32, ptr @h, align 4, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, i32 noundef signext %8)
+ %9 = load i32, ptr @i, align 4, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %9)
+ %10 = load i32, ptr @j, align 4, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, i32 noundef signext %10)
+ %11 = load i32, ptr @k, align 4, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %11)
+ %12 = load i32, ptr @l, align 4, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, i32 noundef signext %12)
+ %13 = load i32, ptr @m, align 4, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, i32 noundef signext %13)
+ %14 = load i32, ptr @n, align 4, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, i32 noundef signext %14)
+ %15 = load i32, ptr @o, align 4, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, i32 noundef signext %15)
+ %16 = load i32, ptr @p, align 4, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, i32 noundef signext %16)
+ %17 = load i32, ptr @q, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, i32 noundef signext %17)
+ %18 = load i32, ptr @r, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, i32 noundef signext %18)
+ %19 = load i32, ptr @s, align 4, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, i32 noundef signext %19)
+ %20 = load i32, ptr @t, align 4, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.22, i32 noundef signext %20)
+ %21 = load i32, ptr @a, align 4, !tbaa !4
+ %22 = load i32, ptr @b, align 4, !tbaa !4
+ %add = add nsw i32 %22, %21
+ %23 = load i32, ptr @c, align 4, !tbaa !4
+ %add22 = add nsw i32 %add, %23
+ %24 = load i32, ptr @d, align 4, !tbaa !4
+ %add23 = add nsw i32 %add22, %24
+ %25 = load i32, ptr @e, align 4, !tbaa !4
+ %add24 = add nsw i32 %add23, %25
+ %26 = load i32, ptr @f, align 4, !tbaa !4
+ %add25 = add nsw i32 %add24, %26
+ %27 = load i32, ptr @g, align 4, !tbaa !4
+ %add26 = add nsw i32 %add25, %27
+ %28 = load i32, ptr @h, align 4, !tbaa !4
+ %add27 = add nsw i32 %add26, %28
+ %29 = load i32, ptr @i, align 4, !tbaa !4
+ %add28 = add nsw i32 %add27, %29
+ %30 = load i32, ptr @j, align 4, !tbaa !4
+ %add29 = add nsw i32 %add28, %30
+ %31 = load i32, ptr @k, align 4, !tbaa !4
+ %add30 = add nsw i32 %add29, %31
+ %32 = load i32, ptr @l, align 4, !tbaa !4
+ %add31 = add nsw i32 %add30, %32
+ %33 = load i32, ptr @m, align 4, !tbaa !4
+ %add32 = add nsw i32 %add31, %33
+ %34 = load i32, ptr @n, align 4, !tbaa !4
+ %add33 = add nsw i32 %add32, %34
+ %35 = load i32, ptr @o, align 4, !tbaa !4
+ %add34 = add nsw i32 %add33, %35
+ %36 = load i32, ptr @p, align 4, !tbaa !4
+ %add35 = add nsw i32 %add34, %36
+ %37 = load i32, ptr @q, align 4, !tbaa !4
+ %add36 = add nsw i32 %add35, %37
+ %38 = load i32, ptr @r, align 4, !tbaa !4
+ %add37 = add nsw i32 %add36, %38
+ %39 = load i32, ptr @s, align 4, !tbaa !4
+ %add38 = add nsw i32 %add37, %39
+ %40 = load i32, ptr @t, align 4, !tbaa !4
+ %add39 = add nsw i32 %add38, %40
+ ret i32 %add39
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+; CHECK: val is 20
+ %call = tail call signext i32 @func()
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.23, i32 noundef signext %call)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noinline nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-02.ll
new file mode 100644
index 00000000000000..9c1586e6aaa1b7
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-02.ll
@@ -0,0 +1,155 @@
+; -mbackchain option
+; Simulate register pressure around setjmp call for integer arguments.
+; Test assembly of funtion call foo in func() in setjmp if and else part.
+; extern foo has 20 argument pointer to int.
+; Test setjmp store jmp_buf.
+; Return address in slot 2.
+; Backchain value in slot 3.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
+; RUN: llc < %s | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-spills-int-02.c'
+source_filename = "builtin-setjmp-spills-int-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local global i32 0, align 4
+ at s = dso_local global i32 0, align 4
+ at r = dso_local global i32 0, align 4
+ at q = dso_local global i32 0, align 4
+ at p = dso_local global i32 0, align 4
+ at o = dso_local global i32 0, align 4
+ at n = dso_local global i32 0, align 4
+ at m = dso_local global i32 0, align 4
+ at l = dso_local global i32 0, align 4
+ at k = dso_local global i32 0, align 4
+ at j = dso_local global i32 0, align 4
+ at i = dso_local global i32 0, align 4
+ at h = dso_local global i32 0, align 4
+ at g = dso_local global i32 0, align 4
+ at f = dso_local global i32 0, align 4
+ at e = dso_local global i32 0, align 4
+ at d = dso_local global i32 0, align 4
+ at c = dso_local global i32 0, align 4
+ at b = dso_local global i32 0, align 4
+ at a = dso_local global i32 0, align 4
+ at str = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local signext i32 @func() local_unnamed_addr #0 {
+entry:
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -344
+; CHECK: std %f8, 336(%r15)
+; CHECK: std %f9, 328(%r15)
+; CHECK: std %f10, 320(%r15)
+; CHECK: std %f11, 312(%r15)
+; CHECK: std %f12, 304(%r15)
+; CHECK: std %f13, 296(%r15)
+; CHECK: std %f14, 288(%r15)
+; CHECK: std %f15, 280(%r15)
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_2
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+; CHECK: lg %r0, 0(%r15)
+; CHECK: stg %r0, 16(%r1)
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ store i32 1, ptr @t, align 4, !tbaa !4
+ store i32 1, ptr @s, align 4, !tbaa !4
+ store i32 1, ptr @r, align 4, !tbaa !4
+ store i32 1, ptr @q, align 4, !tbaa !4
+ store i32 1, ptr @p, align 4, !tbaa !4
+ store i32 1, ptr @o, align 4, !tbaa !4
+ store i32 1, ptr @n, align 4, !tbaa !4
+ store i32 1, ptr @m, align 4, !tbaa !4
+ store i32 1, ptr @l, align 4, !tbaa !4
+ store i32 1, ptr @k, align 4, !tbaa !4
+ store i32 1, ptr @j, align 4, !tbaa !4
+ store i32 1, ptr @i, align 4, !tbaa !4
+ store i32 1, ptr @h, align 4, !tbaa !4
+ store i32 1, ptr @g, align 4, !tbaa !4
+ store i32 1, ptr @f, align 4, !tbaa !4
+ store i32 1, ptr @e, align 4, !tbaa !4
+ store i32 1, ptr @d, align 4, !tbaa !4
+ store i32 1, ptr @c, align 4, !tbaa !4
+ store i32 1, ptr @b, align 4, !tbaa !4
+ store i32 1, ptr @a, align 4, !tbaa !4
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
+ %1 = load i32, ptr @a, align 4, !tbaa !4
+ %2 = load i32, ptr @b, align 4, !tbaa !4
+ %add = add nsw i32 %2, %1
+ %3 = load i32, ptr @c, align 4, !tbaa !4
+ %add1 = add nsw i32 %add, %3
+ %4 = load i32, ptr @d, align 4, !tbaa !4
+ %add2 = add nsw i32 %add1, %4
+ %5 = load i32, ptr @e, align 4, !tbaa !4
+ %add3 = add nsw i32 %add2, %5
+ %6 = load i32, ptr @f, align 4, !tbaa !4
+ %add4 = add nsw i32 %add3, %6
+ %7 = load i32, ptr @g, align 4, !tbaa !4
+ %add5 = add nsw i32 %add4, %7
+ %8 = load i32, ptr @h, align 4, !tbaa !4
+ %add6 = add nsw i32 %add5, %8
+ %9 = load i32, ptr @i, align 4, !tbaa !4
+ %add7 = add nsw i32 %add6, %9
+ %10 = load i32, ptr @j, align 4, !tbaa !4
+ %add8 = add nsw i32 %add7, %10
+ %11 = load i32, ptr @k, align 4, !tbaa !4
+ %add9 = add nsw i32 %add8, %11
+ %12 = load i32, ptr @l, align 4, !tbaa !4
+ %add10 = add nsw i32 %add9, %12
+ %13 = load i32, ptr @m, align 4, !tbaa !4
+ %add11 = add nsw i32 %add10, %13
+ %14 = load i32, ptr @n, align 4, !tbaa !4
+ %add12 = add nsw i32 %add11, %14
+ %15 = load i32, ptr @o, align 4, !tbaa !4
+ %add13 = add nsw i32 %add12, %15
+ %16 = load i32, ptr @p, align 4, !tbaa !4
+ %add14 = add nsw i32 %add13, %16
+ %17 = load i32, ptr @q, align 4, !tbaa !4
+ %add15 = add nsw i32 %add14, %17
+ %18 = load i32, ptr @r, align 4, !tbaa !4
+ %add16 = add nsw i32 %add15, %18
+ %19 = load i32, ptr @s, align 4, !tbaa !4
+ %add17 = add nsw i32 %add16, %19
+ %20 = load i32, ptr @t, align 4, !tbaa !4
+ %add18 = add nsw i32 %add17, %20
+ ret i32 %add18
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
+
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #2
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #3
+
+attributes #0 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nounwind }
+attributes #2 = { "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-03.ll
new file mode 100644
index 00000000000000..e1ece2c3010fa7
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-03.ll
@@ -0,0 +1,227 @@
+; -mbackchain option.
+; Simulate register pressure around setjmp call for integer arguments and
+; return sum of 20 vaiables. It also prints the variables.
+; Test assembly of funtion call foo in func() in setjmp if and else part.
+; extern foo has 20 argument pointer to int.
+; Test setjmp store jmp_buf.
+; Return address in slot 2.
+; Backchain value in slot 3.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
+; RUN: llc < %s | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-spills-int-03.c'
+source_filename = "builtin-setjmp-spills-int-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [10 x ptr] zeroinitializer, align 8
+ at t = dso_local global i32 0, align 4
+ at s = dso_local global i32 0, align 4
+ at r = dso_local global i32 0, align 4
+ at q = dso_local global i32 0, align 4
+ at p = dso_local global i32 0, align 4
+ at o = dso_local global i32 0, align 4
+ at n = dso_local global i32 0, align 4
+ at m = dso_local global i32 0, align 4
+ at l = dso_local global i32 0, align 4
+ at k = dso_local global i32 0, align 4
+ at j = dso_local global i32 0, align 4
+ at i = dso_local global i32 0, align 4
+ at h = dso_local global i32 0, align 4
+ at g = dso_local global i32 0, align 4
+ at f = dso_local global i32 0, align 4
+ at e = dso_local global i32 0, align 4
+ at d = dso_local global i32 0, align 4
+ at c = dso_local global i32 0, align 4
+ at b = dso_local global i32 0, align 4
+ at a = dso_local global i32 0, align 4
+ at .str.2 = private unnamed_addr constant [8 x i8] c"a = %d\0A\00", align 2
+ at .str.3 = private unnamed_addr constant [8 x i8] c"b = %d\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [8 x i8] c"c = %d\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [8 x i8] c"d = %d\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [8 x i8] c"e = %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [8 x i8] c"f = %d\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [8 x i8] c"g = %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [8 x i8] c"h = %d\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [8 x i8] c"j = %d\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [8 x i8] c"k = %d\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [8 x i8] c"l = %d\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [8 x i8] c"m = %d\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [8 x i8] c"n = %d\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [8 x i8] c"o = %d\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [8 x i8] c"p = %d\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [8 x i8] c"q = %d\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [8 x i8] c"r = %d\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [8 x i8] c"s = %d\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [8 x i8] c"t = %d\0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.22 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+
+; Function Attrs: nounwind
+define dso_local signext i32 @func() local_unnamed_addr #0 {
+entry:
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: ghi %r15, -344
+; CHECK: std %f8, 336(%r15)
+; CHECK: std %f9, 328(%r15)
+; CHECK: std %f10, 320(%r15)
+; CHECK: std %f11, 312(%r15)
+; CHECK: std %f12, 304(%r15)
+; CHECK: std %f13, 296(%r15)
+; CHECK: std %f14, 288(%r15)
+; CHECK: std %f15, 280(%r15)
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_3
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+; CHECK: lg %r0, 0(%r15)
+; CHECK: stg %r0, 16(%r1)
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ store i32 1, ptr @t, align 4, !tbaa !4
+ store i32 1, ptr @s, align 4, !tbaa !4
+ store i32 1, ptr @r, align 4, !tbaa !4
+ store i32 1, ptr @q, align 4, !tbaa !4
+ store i32 1, ptr @p, align 4, !tbaa !4
+ store i32 1, ptr @o, align 4, !tbaa !4
+ store i32 1, ptr @n, align 4, !tbaa !4
+ store i32 1, ptr @m, align 4, !tbaa !4
+ store i32 1, ptr @l, align 4, !tbaa !4
+ store i32 1, ptr @k, align 4, !tbaa !4
+ store i32 1, ptr @j, align 4, !tbaa !4
+ store i32 1, ptr @i, align 4, !tbaa !4
+ store i32 1, ptr @h, align 4, !tbaa !4
+ store i32 1, ptr @g, align 4, !tbaa !4
+ store i32 1, ptr @f, align 4, !tbaa !4
+ store i32 1, ptr @e, align 4, !tbaa !4
+ store i32 1, ptr @d, align 4, !tbaa !4
+ store i32 1, ptr @c, align 4, !tbaa !4
+ store i32 1, ptr @b, align 4, !tbaa !4
+ store i32 1, ptr @a, align 4, !tbaa !4
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
+ br label %if.end
+
+if.else: ; preds = %entry
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ %1 = load i32, ptr @a, align 4, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %1)
+ %2 = load i32, ptr @b, align 4, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %2)
+ %3 = load i32, ptr @c, align 4, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %3)
+ %4 = load i32, ptr @d, align 4, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, i32 noundef signext %4)
+ %5 = load i32, ptr @e, align 4, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %5)
+ %6 = load i32, ptr @f, align 4, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %6)
+ %7 = load i32, ptr @g, align 4, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %7)
+ %8 = load i32, ptr @h, align 4, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %8)
+ %9 = load i32, ptr @i, align 4, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, i32 noundef signext %9)
+ %10 = load i32, ptr @j, align 4, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %10)
+ %11 = load i32, ptr @k, align 4, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, i32 noundef signext %11)
+ %12 = load i32, ptr @l, align 4, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %12)
+ %13 = load i32, ptr @m, align 4, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, i32 noundef signext %13)
+ %14 = load i32, ptr @n, align 4, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, i32 noundef signext %14)
+ %15 = load i32, ptr @o, align 4, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, i32 noundef signext %15)
+ %16 = load i32, ptr @p, align 4, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, i32 noundef signext %16)
+ %17 = load i32, ptr @q, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, i32 noundef signext %17)
+ %18 = load i32, ptr @r, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, i32 noundef signext %18)
+ %19 = load i32, ptr @s, align 4, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, i32 noundef signext %19)
+ %20 = load i32, ptr @t, align 4, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, i32 noundef signext %20)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %21 = load i32, ptr @a, align 4, !tbaa !4
+ %22 = load i32, ptr @b, align 4, !tbaa !4
+ %add = add nsw i32 %22, %21
+ %23 = load i32, ptr @c, align 4, !tbaa !4
+ %add22 = add nsw i32 %add, %23
+ %24 = load i32, ptr @d, align 4, !tbaa !4
+ %add23 = add nsw i32 %add22, %24
+ %25 = load i32, ptr @e, align 4, !tbaa !4
+ %add24 = add nsw i32 %add23, %25
+ %26 = load i32, ptr @f, align 4, !tbaa !4
+ %add25 = add nsw i32 %add24, %26
+ %27 = load i32, ptr @g, align 4, !tbaa !4
+ %add26 = add nsw i32 %add25, %27
+ %28 = load i32, ptr @h, align 4, !tbaa !4
+ %add27 = add nsw i32 %add26, %28
+ %29 = load i32, ptr @i, align 4, !tbaa !4
+ %add28 = add nsw i32 %add27, %29
+ %30 = load i32, ptr @j, align 4, !tbaa !4
+ %add29 = add nsw i32 %add28, %30
+ %31 = load i32, ptr @k, align 4, !tbaa !4
+ %add30 = add nsw i32 %add29, %31
+ %32 = load i32, ptr @l, align 4, !tbaa !4
+ %add31 = add nsw i32 %add30, %32
+ %33 = load i32, ptr @m, align 4, !tbaa !4
+ %add32 = add nsw i32 %add31, %33
+ %34 = load i32, ptr @n, align 4, !tbaa !4
+ %add33 = add nsw i32 %add32, %34
+ %35 = load i32, ptr @o, align 4, !tbaa !4
+ %add34 = add nsw i32 %add33, %35
+ %36 = load i32, ptr @p, align 4, !tbaa !4
+ %add35 = add nsw i32 %add34, %36
+ %37 = load i32, ptr @q, align 4, !tbaa !4
+ %add36 = add nsw i32 %add35, %37
+ %38 = load i32, ptr @r, align 4, !tbaa !4
+ %add37 = add nsw i32 %add36, %38
+ %39 = load i32, ptr @s, align 4, !tbaa !4
+ %add38 = add nsw i32 %add37, %39
+ %40 = load i32, ptr @t, align 4, !tbaa !4
+ %add39 = add nsw i32 %add38, %40
+ ret i32 %add39
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #2
+
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #3
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #4
+
+attributes #0 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nounwind }
+attributes #2 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
>From 7500b72c08737a987d5fe48c9d56b2e37b52af64 Mon Sep 17 00:00:00 2001
From: anoop-kumar6 <anoop.kumar6 at ibm.com>
Date: Fri, 25 Oct 2024 14:55:59 +0200
Subject: [PATCH 3/9] Incorporating code review feedback and adding test cases
for builtin setjmp/longjmp.
---
clang/lib/CodeGen/CGBuiltin.cpp | 10 +-
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 4 +-
.../Target/SystemZ/SystemZISelLowering.cpp | 107 +++---
llvm/lib/Target/SystemZ/SystemZISelLowering.h | 5 -
llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 2 +-
llvm/lib/Target/SystemZ/SystemZLongBranch.cpp | 2 +
llvm/lib/Target/SystemZ/SystemZOperators.td | 4 +-
.../CodeGen/SystemZ/builtin-longjmp-01.ll | 26 +-
.../SystemZ/builtin-longjmp-backchain-01.ll | 28 +-
.../test/CodeGen/SystemZ/builtin-setjmp-01.ll | 67 ++--
.../SystemZ/builtin-setjmp-backchain-01.ll | 76 ++---
.../SystemZ/builtin-setjmp-longjmp-01.ll | 1 +
.../SystemZ/builtin-setjmp-longjmp-02.ll | 93 +++--
.../builtin-setjmp-longjmp-alloca-01.ll | 35 +-
.../builtin-setjmp-longjmp-alloca-02.ll | 4 +
...ltin-setjmp-longjmp-alloca-backchain-02.ll | 6 +
.../builtin-setjmp-longjmp-backchain-01.ll | 2 +
.../builtin-setjmp-longjmp-backchain-02.ll | 100 +++---
.../builtin-setjmp-spills-double-01.ll | 323 ++++++++++--------
.../builtin-setjmp-spills-double-02.ll | 120 ++++---
.../builtin-setjmp-spills-double-03.ll | 208 ++++++-----
.../SystemZ/builtin-setjmp-spills-int-01.ll | 321 +++++++++--------
.../SystemZ/builtin-setjmp-spills-int-02.ll | 120 ++++---
.../SystemZ/builtin-setjmp-spills-int-03.ll | 207 ++++++-----
24 files changed, 973 insertions(+), 898 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 31edd05a18e294..21f9b8667821c8 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4542,6 +4542,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// Buffer is a void**.
Address Buf = EmitPointerWithAlignment(E->getArg(0));
+ if (getTarget().getTriple().getArch() == llvm::Triple::systemz) {
+ // Call LLVM's EH setjmp, which is lightweight.
+ Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
+ return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this)));
+ }
+
// Store the frame pointer to the setjmp buffer.
Value *FrameAddr = Builder.CreateCall(
CGM.getIntrinsic(Intrinsic::frameaddress, AllocaInt8PtrTy),
@@ -4552,9 +4558,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *StackAddr = Builder.CreateStackSave();
assert(Buf.emitRawPointer(*this)->getType() == StackAddr->getType());
- //StackSaveSlot no is hard coded here. For compatility with gcc,
- // we are changing slot 3 to slot 4(offset 3) for __builtin_setjmp
- Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 3);
+ Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 2);
Builder.CreateStore(StackAddr, StackSaveSlot);
// Call LLVM's EH setjmp, which is lightweight.
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 0f7e8560d5ecf3..f6e3feca70c827 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -686,8 +686,8 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
MCInstBuilder(SystemZ::EXRL).addReg(LenMinus1Reg).addExpr(Dot));
return;
}
- //EH_SjLj_Setup is a dummy terminator instruction of size 0,
- //used to handle the clobber register for builtin sejmp
+ // EH_SjLj_Setup is a dummy terminator instruction of size 0,
+ // It is used to handle the clobber register for builtin setjmp.
case SystemZ::EH_SjLj_Setup:
return;
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 43b0aecd8b499d..983215bf28519e 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -747,15 +747,11 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
ISD::INTRINSIC_VOID,
ISD::INTRINSIC_W_CHAIN});
- // First try assuming that any undefined bits above the highest set bit
- // and below the lowest set bit are 1s. This increases the likelihood of
- // being able to use a sign-extended element value in VECTOR REPLICATE
- // IMMEDIATE or a wraparound mask in VECTOR GENERATE MASK.
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
- //we're not using SJLJ for exception handling, but they're implemented
- //solely to support use of __builtin_setjmp / __builtin_longjmp
+ // we're not using SJLJ for exception handling, but they're implemented
+ // solely to support use of __builtin_setjmp / __builtin_longjmp.
setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
@@ -947,6 +943,7 @@ bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
return SystemZVectorConstantInfo(Imm).isVectorConstantLegal(Subtarget);
}
+
MachineBasicBlock *
SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
MachineBasicBlock *MBB) const {
@@ -970,7 +967,7 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
MVT PVT = getPointerTy(MF->getDataLayout());
assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
- // For v = setjmp(buf), we generate
+ // For v = setjmp(buf), we generate.
// Algorithm:
//
// ---------
@@ -991,14 +988,18 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
// | phi(v_mainMBB,v_restoreMBB) |
// -----------------------------
// thisMBB:
- // buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB
+ // buf[0] = Frame Pointer if hasFP.
+ // buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB.
+ // buf[BCOffset] = Backchain value if building with -mbackchain.
+ // buf[SPOffset] = Stack Pointer.
+ // buf[LPOffset] = Literal Pool Pointer if R13 live.
// SjLjSetup restoreMBB
//
// mainMBB:
// v_main = 0
//
// sinkMBB:
- // v = phi(main, restore)
+ // v = phi(v_main, v_restore)
//
// restoreMBB:
// v_restore = 1
@@ -1007,6 +1008,7 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(BB);
MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB);
MachineBasicBlock *restoreMBB = MF->CreateMachineBasicBlock(BB);
+
MF->insert(I, mainMBB);
MF->insert(I, sinkMBB);
MF->push_back(restoreMBB);
@@ -1019,52 +1021,46 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
std::next(MachineBasicBlock::iterator(MI)), MBB->end());
sinkMBB->transferSuccessorsAndUpdatePHIs(MBB);
- // Note that the structure of the jmp_buf used here is not compatible
- // with that used by libc, and is not designed to be. Specifically, it
- // stores only those 'reserved' registers that LLVM does not otherwise
- // understand how to spill. Also, by convention, by the time this
- // intrinsic is called, Clang has already stored the frame address in the
- // first slot of the buffer and stack address in the third(gcc stores SP in
- // fourth slot).
- // clang convention:
- // -----------------
- // slot 1(Offset 0): Frame Pointer
- // slot 3(Offset 2): Stack Pointer
- // GCC following convetion :
- // ------------------------
- // Slot 1(Offset 0): Frame pointer
- // Slot 2(Offset 1): Receiver (jump) address
- // Slot 3(Offset 2): Backchain value (if building with -mbackchain)
- // Slot 4(Offset 3): Stack pointer
- // Slot 5(Offset 4): R13 (used to be literal pool pointer)
- // We have made changes to clang/lib/CodeGen/CGBuiltin.cpp to change
- // stack slot to 4(offset = 3) instead of 3 to keep it in sync with gcc
- // Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 3);
// thisMBB:
- const int64_t LabelOffset = 1 * PVT.getStoreSize(); //Slot 2
- const int64_t LPOffset = 4 * PVT.getStoreSize(); //Slot 5
+ const int64_t LabelOffset = 1 * PVT.getStoreSize(); // Slot 2.
+ const int64_t SPOffset = 3 * PVT.getStoreSize(); // Slot 4.
- //Buf address
+ // Buf address.
Register BufReg = MI.getOperand(1).getReg();
unsigned LabelReg = 0;
const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
LabelReg = MRI.createVirtualRegister(PtrRC);
- //prepare IP for longjmp
+ // prepare IP for longjmp.
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LARL), LabelReg)
.addMBB(restoreMBB);
- //store IP for return from jmp, slot 2, offset = 1
+ // store IP for return from jmp, slot 2, offset = 1.
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
- .addReg(LabelReg, getKillRegState(true))
+ .addReg(LabelReg)
.addReg(BufReg)
.addImm(LabelOffset)
.addReg(0);
+ bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
+ if (HasFP || MBB->isLiveIn(SystemZ::R11D)) {
+ BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
+ .addReg(SystemZ::R11D)
+ .addReg(BufReg)
+ .addImm(0)
+ .addReg(0);
+ }
+
+ // store SP.
+ BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
+ .addReg(SystemZ::R15D)
+ .addReg(BufReg)
+ .addImm(SPOffset)
+ .addReg(0);
- //Slot 3(Offset = 2) Backchain value (if building with -mbackchain)
+ // Slot 3(Offset = 2) Backchain value (if building with -mbackchain).
bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain();
if (BackChain) {
const int64_t BCOffset = 2 * PVT.getStoreSize();
@@ -1081,14 +1077,19 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
.addReg(0);
}
- //LP Literal Pool in fifth slot, offset 4
- BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
+ // LP Literal Pool register in fifth slot.
+ if (MBB->isLiveIn(SystemZ::R13D)) {
+ // If R13 is not live, and It is non-reserved physical register, we get
+ // assertion - Using an undefined physical register.
+ const int64_t LPOffset = 4 * PVT.getStoreSize(); // Slot 5.
+ BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
.addReg(SystemZ::R13D)
.addReg(BufReg)
.addImm(LPOffset)
.addReg(0);
+ }
- //Setup
+ // Setup.
MIB = BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::EH_SjLj_Setup))
.addMBB(restoreMBB);
@@ -1099,8 +1100,7 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
thisMBB->addSuccessor(restoreMBB);
// mainMBB:
- // mainDstReg = 0
- BuildMI(mainMBB, DL, TII->get(SystemZ::LGHI), mainDstReg).addImm(0);
+ BuildMI(mainMBB, DL, TII->get(SystemZ::LHI), mainDstReg).addImm(0);
mainMBB->addSuccessor(sinkMBB);
// sinkMBB:
@@ -1110,8 +1110,8 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
.addReg(restoreDstReg)
.addMBB(restoreMBB);
- //restoreMBB
- BuildMI(restoreMBB, DL, TII->get(SystemZ::LGHI), restoreDstReg).addImm(1);
+ // restoreMBB.
+ BuildMI(restoreMBB, DL, TII->get(SystemZ::LHI), restoreDstReg).addImm(1);
BuildMI(restoreMBB, DL, TII->get(SystemZ::J)).addMBB(sinkMBB);
restoreMBB->addSuccessor(sinkMBB);
@@ -1149,14 +1149,14 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
.addImm(LabelOffset)
.addReg(0);
- MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R13D)
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R11D)
.addReg(BufReg)
- .addImm(LPOffset)
+ .addImm(0)
.addReg(0);
- MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R15D)
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R13D)
.addReg(BufReg)
- .addImm(SPOffset)
+ .addImm(LPOffset)
.addReg(0);
bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain();
@@ -1175,6 +1175,11 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
.addReg(0);
}
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R15D)
+ .addReg(BufReg)
+ .addImm(SPOffset)
+ .addReg(0);
+
MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::BR)).addReg(Tmp);
MI.eraseFromParent();
@@ -6783,8 +6788,6 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
OPCODE(VSTRS_CC);
OPCODE(VSTRSZ_CC);
OPCODE(TDC);
- OPCODE(EH_SJLJ_SETJMP);
- OPCODE(EH_SJLJ_LONGJMP);
OPCODE(ATOMIC_SWAPW);
OPCODE(ATOMIC_LOADW_ADD);
OPCODE(ATOMIC_LOADW_SUB);
@@ -10042,7 +10045,7 @@ SDValue SystemZTargetLowering::lowerGET_ROUNDING(SDValue Op,
SDValue SystemZTargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
- return DAG.getNode(SystemZISD::EH_SJLJ_SETJMP, DL,
+ return DAG.getNode(ISD::EH_SJLJ_SETJMP, DL,
DAG.getVTList(MVT::i32, MVT::Other),
Op.getOperand(0), Op.getOperand(1));
}
@@ -10050,7 +10053,7 @@ SDValue SystemZTargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
SDValue SystemZTargetLowering::lowerEH_SJLJ_LONGJMP(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
- return DAG.getNode(SystemZISD::EH_SJLJ_LONGJMP, DL, MVT::Other,
+ return DAG.getNode(ISD::EH_SJLJ_LONGJMP, DL, MVT::Other,
Op.getOperand(0), Op.getOperand(1));
}
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index e192c7dad07318..e6846a78245dc2 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -304,11 +304,6 @@ enum NodeType : unsigned {
// Operand 2: the offset (0 for the first and 8 for the second element in the
// function descriptor)
ADA_ENTRY,
- // EH_SJLJ_SETJMP - SjLj exception handling setjmp.
- EH_SJLJ_SETJMP,
-
- // EH_SJLJ_LONGJMP - SjLj exception handling longjmp.
- EH_SJLJ_LONGJMP,
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index b7af22bf4aa8af..fc005ae451b06d 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -1872,7 +1872,7 @@ let mayLoad = 1, mayStore = 1, Defs = [CC] in {
}
//--------------------------------------------------------------------------
-// Setjmp/Longjmp
+// Setjmp/Longjmp.
//--------------------------------------------------------------------------
let isTerminator = 1, isBarrier = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1, Size = 0 in {
def EH_SjLj_Setup : Pseudo<(outs), (ins brtarget32:$dst), []>;
diff --git a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp
index cd60f23a9cbb3d..8267d398c50ed6 100644
--- a/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZLongBranch.cpp
@@ -221,6 +221,8 @@ static unsigned getInstSizeInBytes(const MachineInstr &MI,
// These have a size that may be zero:
MI.isInlineAsm() || MI.getOpcode() == SystemZ::STACKMAP ||
MI.getOpcode() == SystemZ::PATCHPOINT ||
+ // EH_SjLj_Setup is a dummy terminator instruction of size 0,
+ // It is used to handle the clobber register for builtin setjmp.
MI.getOpcode() == SystemZ::EH_SjLj_Setup) &&
"Missing size value for instruction.");
return Size;
diff --git a/llvm/lib/Target/SystemZ/SystemZOperators.td b/llvm/lib/Target/SystemZ/SystemZOperators.td
index 89c99d31e3c92e..90fb4e5f370dab 100644
--- a/llvm/lib/Target/SystemZ/SystemZOperators.td
+++ b/llvm/lib/Target/SystemZ/SystemZOperators.td
@@ -320,9 +320,9 @@ def z_stckf : SDNode<"SystemZISD::STCKF", SDT_ZStoreInherent,
def z_tdc : SDNode<"SystemZISD::TDC", SDT_ZTest>;
-def z_eh_sjlj_setjmp : SDNode<"SystemZISD::EH_SJLJ_SETJMP", SDT_ZSetJmp,
+def z_eh_sjlj_setjmp : SDNode<"ISD::EH_SJLJ_SETJMP", SDT_ZSetJmp,
[SDNPHasChain, SDNPSideEffect]>;
-def z_eh_sjlj_longjmp : SDNode<"SystemZISD::EH_SJLJ_LONGJMP", SDT_ZLongJmp,
+def z_eh_sjlj_longjmp : SDNode<"ISD::EH_SJLJ_LONGJMP", SDT_ZLongJmp,
[SDNPHasChain, SDNPSideEffect]>;
diff --git a/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll b/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll
index 7e6667cb87ccd0..fb6f19bbb9e05a 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll
@@ -1,4 +1,12 @@
-; RUN: llc < %s -verify-machineinstrs | FileCheck %s
+;Test longjmp load from jmp_buf.
+; Frame pointer from Slot 1.
+; Jump address from Slot 2.
+; Stack Pointer from Slot 4.
+; Literal Pool Pointer from Slot 5.
+
+; RUN: llc < %s | FileCheck %s
+
+
; ModuleID = 'longjmp.c'
source_filename = "longjmp.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -9,12 +17,14 @@ target triple = "s390x-unknown-linux-gnu"
; Function Attrs: noreturn nounwind
define dso_local void @foo() local_unnamed_addr #0 {
entry:
-; CHECK: stmg %r13, %r15, 104(%r15)
-; CHECK: larl %r1, buf
-; CHECK: lg %r2, 8(%r1)
-; CHECK: lg %r13, 32(%r1)
-; CHECK: lg %r15, 24(%r1)
-; CHECK: br %r2
+; CHECK: stmg %r11, %r15, 88(%r15)
+; CHECK: larl %r1, buf
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r11, 0(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: br %r2
+
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
unreachable
}
@@ -31,4 +41,4 @@ attributes #1 = { noreturn nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
index 137dd754892b28..dde5b7ea498dbc 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
@@ -1,4 +1,12 @@
+;Test -mbackchain longjmp load from jmp_buf.
+; Frame pointer from Slot 1.
+; Jump address from Slot 2.
+; Backchain Value from Slot 3.
+; Stack Pointer from Slot 4.
+; Literal Pool Pointer from Slot 5.
+
; RUN: llc < %s | FileCheck %s
+
; ModuleID = 'longjmp.c'
source_filename = "longjmp.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -9,14 +17,16 @@ target triple = "s390x-unknown-linux-gnu"
; Function Attrs: noreturn nounwind
define dso_local void @foo() local_unnamed_addr #0 {
entry:
-; CHECK: stmg %r13, %r15, 104(%r15)
-; CHECK: larl %r1, buf
-; CHECK: lg %r2, 8(%r1)
-; CHECK: lg %r13, 32(%r1)
-; CHECK: lg %r15, 24(%r1)
-; CHECK: lg %r1, 16(%r1)
-; CHECK: stg %r1, 0(%r15)
-; CHECK: br %r2
+; CHECK: stmg %r11, %r15, 88(%r15)
+; CHECK: larl %r1, buf
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r11, 0(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r3, 16(%r1)
+; CHECK: stg %r3, 0(%r15)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: br %r2
+
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
unreachable
}
@@ -33,4 +43,4 @@ attributes #1 = { noreturn nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-01.ll
index 3f22e6d3699575..b6d5290d48b761 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-01.ll
@@ -1,4 +1,10 @@
-; RUN: llc < %s | FileCheck %s
+; Test setjmp store jmp_buf
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
+; RUN: llc < %s | FileCheck %s
+
; ModuleID = 'setjmp.c'
source_filename = "setjmp.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -9,33 +15,26 @@ target triple = "s390x-unknown-linux-gnu"
; Function Attrs: nounwind
define dso_local signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #0 {
entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
-; CHECK: stmg %r6, %r15, 48(%r15)
-; CHECK: ghi %r15, -224
-; CHECK: std %f8, 216(%r15)
-; CHECK: std %f9, 208(%r15)
-; CHECK: std %f10, 200(%r15)
-; CHECK: std %f11, 192(%r15)
-; CHECK: std %f12, 184(%r15)
-; CHECK: std %f13, 176(%r15)
-; CHECK: std %f14, 168(%r15)
-; CHECK: std %f15, 160(%r15)
-; CHECK: la %r0, 224(%r15)
-; CHECK: stgrl %r0, buf
-; CHECK: stgrl %r15, buf+24
-; CHECK: larl %r1, buf
-; CHECK: larl %r0, .LBB0_2
-; CHECK: stg %r0, 8(%r1)
-; CHECK: stg %r13, 32(%r1)
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %tobool.not = icmp eq i32 %2, 0
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: aghi %r15, -224
+; CHECK: std %f8, 216(%r15)
+; CHECK: std %f9, 208(%r15)
+; CHECK: std %f10, 200(%r15)
+; CHECK: std %f11, 192(%r15)
+; CHECK: std %f12, 184(%r15)
+; CHECK: std %f13, 176(%r15)
+; CHECK: std %f14, 168(%r15)
+; CHECK: std %f15, 160(%r15)
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_2
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %tobool.not = icmp eq i32 %0, 0
br i1 %tobool.not, label %if.end, label %return
if.end: ; preds = %entry
- tail call void @foo() #3
+ tail call void @foo() #1
br label %return
return: ; preds = %entry, %if.end
@@ -43,22 +42,14 @@ return: ; preds = %entry, %if.end
ret i32 %retval.0
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #1
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #2
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
-declare void @foo() local_unnamed_addr #4
+declare void @foo() local_unnamed_addr #2
attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #3 = { nounwind }
-attributes #4 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nounwind }
+attributes #2 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -66,4 +57,4 @@ attributes #4 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "t
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-backchain-01.ll
index da281cd6aef710..a3c8a7d04639e8 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-backchain-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-backchain-01.ll
@@ -1,4 +1,10 @@
-; RUN: llc < %s | FileCheck %s
+; Test -mbackchain setjmp store jmp_buf
+; Return address in slot 2.
+; Backchain value in slot 3.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
+; RUN: llc < %s | FileCheck %s
; ModuleID = 'setjmp.c'
source_filename = "setjmp.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -9,37 +15,31 @@ target triple = "s390x-unknown-linux-gnu"
; Function Attrs: nounwind
define dso_local signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #0 {
entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
-; CHECK: stmg %r6, %r15, 48(%r15)
-; CHECK: lgr %r1, %r15
-; CHECK: aghi %r15, -224
-; CHECK: stg %r1, 0(%r15)
-; CHECK: std %f8, 216(%r15)
-; CHECK: std %f9, 208(%r15)
-; CHECK: std %f10, 200(%r15)
-; CHECK: std %f11, 192(%r15)
-; CHECK: std %f12, 184(%r15)
-; CHECK: std %f13, 176(%r15)
-; CHECK: std %f14, 168(%r15)
-; CHECK: std %f15, 160(%r15)
-; CHECK: la %r0, 224(%r15)
-; CHECK: stgrl %r0, buf
-; CHECK: stgrl %r15, buf+24
-; CHECK: larl %r1, buf
-; CHECK: larl %r0, .LBB0_2
-; CHECK: stg %r0, 8(%r1)
-; CHECK: lg %r0, 0(%r15)
-; CHECK: stg %r0, 16(%r1)
-; CHECK: stg %r13, 32(%r1)
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %tobool.not = icmp eq i32 %2, 0
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: lgr %r1, %r15
+; CHECK: aghi %r15, -224
+; CHECK: stg %r1, 0(%r15)
+; CHECK: std %f8, 216(%r15)
+; CHECK: std %f9, 208(%r15)
+; CHECK: std %f10, 200(%r15)
+; CHECK: std %f11, 192(%r15)
+; CHECK: std %f12, 184(%r15)
+; CHECK: std %f13, 176(%r15)
+; CHECK: std %f14, 168(%r15)
+; CHECK: std %f15, 160(%r15)
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB0_2
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+; CHECK: lg %r0, 0(%r15)
+; CHECK: stg %r0, 16(%r1)
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %tobool.not = icmp eq i32 %0, 0
br i1 %tobool.not, label %if.end, label %return
if.end: ; preds = %entry
- tail call void @foo() #3
+ tail call void @foo() #1
br label %return
return: ; preds = %entry, %if.end
@@ -47,22 +47,14 @@ return: ; preds = %entry, %if.end
ret i32 %retval.0
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #1
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #2
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
-declare void @foo() local_unnamed_addr #4
+declare void @foo() local_unnamed_addr #2
attributes #0 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #3 = { nounwind }
-attributes #4 = { "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nounwind }
+attributes #2 = { "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -70,4 +62,4 @@ attributes #4 = { "backchain" "no-trapping-math"="true" "stack-protector-buffer-
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-01.ll
index 98a5c4c1e77fbe..2452504bfa9179 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-01.ll
@@ -1,3 +1,4 @@
+; Test output of setjmp/longjmp.
; RUN: clang -o %t %s
; RUN: %t | FileCheck %s
; CHECK: call foo
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll
index c8d52e876aef54..07307e91d07b04 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll
@@ -1,22 +1,37 @@
-;
+;Test longjmp load from jmp_buf.
+; Frame pointer from Slot 1.
+; Jump address from Slot 2.
+; Stack Pointer from Slot 4.
+; Literal Pool Pointer from Slot 5.
+
; RUN: llc < %s | FileCheck %s
+; CHECK: stmg %r11, %r15, 88(%r15)
+; CHECK: aghi %r15, -160
+; CHECK: lgrl %r2, .Lstr at GOT
+; CHECK: brasl %r14, puts at PLT
+; CHECK: larl %r1, buf
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r11, 0(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: br %r2
-; ModuleID = 't.c'
-source_filename = "t.c"
+; ModuleID = 'builtin-setjmp-longjmp-02.c'
+source_filename = "builtin-setjmp-longjmp-02.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
target triple = "s390x-unknown-linux-gnu"
@buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+ at str.7 = private unnamed_addr constant [23 x i8] c"setjmp has been called\00", align 1
+ at str.8 = private unnamed_addr constant [21 x i8] c"Calling function foo\00", align 1
+ at str.10 = private unnamed_addr constant [24 x i8] c"longjmp has been called\00", align 1
; Function Attrs: noreturn nounwind
define dso_local void @foo() local_unnamed_addr #0 {
entry:
-; CHECK: stmg %r13, %r15, 104(%r15)
-; CHECK: larl %r1, buf
-; CHECK: lg %r2, 8(%r1)
-; CHECK: lg %r13, 32(%r1)
-; CHECK: lg %r15, 24(%r1)
-; CHECK: br %r2
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
unreachable
}
@@ -24,40 +39,54 @@ entry:
; Function Attrs: noreturn nounwind
declare void @llvm.eh.sjlj.longjmp(ptr) #1
-; Function Attrs: nounwind
-define dso_local noundef signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #2 {
+; Function Attrs: nofree nounwind
+define dso_local void @recover() local_unnamed_addr #2 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #0 {
entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %tobool.not = icmp eq i32 %2, 0
- br i1 %tobool.not, label %if.end, label %return
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ br i1 %cmp.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %puts6 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 1) #6
+ unreachable
if.end: ; preds = %entry
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB2_3
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.7)
+ %puts4 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.8)
+ %puts.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
unreachable
-
-return: ; preds = %entry
- ret i32 0
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #3
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #4
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #4
-; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #5
attributes #0 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #1 = { noreturn nounwind }
-attributes #2 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #3 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #5 = { nounwind }
+attributes #2 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { nounwind }
+attributes #4 = { nofree noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { nofree nounwind }
+attributes #6 = { cold noreturn nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -65,4 +94,4 @@ attributes #5 = { nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll
index 22f35e5e2e0a08..c3105c0085470a 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll
@@ -1,9 +1,11 @@
-; Producing wrong result.
; llvm-lit does not take input from stdin, test case produces right result.
; This test case produces right result when alloca size is unknown.
; Test output of setjmp/longjmp with nested setjmp for alloca
; Test for Frame Pointer in first slot in jmp_buf.
-; sum(regsiter pressure).
+
+; FIXME: Take input from stdin for size of alloca.
+; TODO: -mbackchain
+
; RUN: clang -o %t %s
; RUN: %t | FileCheck %s
@@ -71,17 +73,30 @@ if.then: ; preds = %entry
if.then7: ; preds = %if.then
%puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
; CHECK: Returned from func3
; CHECK: arr: 0
-; CHECK: arr: 3
-; CHECK: arr: 14
+; CHECK: arr: 3
+; CHECK: arr: 14
; CHECK: arr: 39
-; CHECK: arr: 84
-; CHECK: arr: 155
-; CHECK: arr: 258
-; CHECK: arr: 399
-; CHECK: arr: 584
-; CHECK: arr: 819
+; CHECK: arr: 84
+; CHECK: arr: 155
+; CHECK: arr: 258
+; CHECK: arr: 399
+; CHECK: arr: 584
+; CHECK: arr: 819
tail call void @func4()
unreachable
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll
index aaf711cc512066..1a24e0f0ee12d1 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll
@@ -3,6 +3,10 @@
; This test case takes input from stdin for size of alloca
; and produce the right result.
+; Frame Pointer in slot 1.
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+
; RUN: llc < %s | FileCheck %s
; ModuleID = 'builtin-setjmp-longjmp-alloca-01.c'
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll
index 0e81b71af79df2..2cb2b885ee985c 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll
@@ -3,6 +3,12 @@
; Test assembly for nested setjmp for alloa.
; This test case takes input from stdin for size of alloca
; and produce the right result.
+; Frame Pointer in slot 1.
+; Return address in slot 2.
+; Backchain value in slot 3.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
; RUN: llc < %s | FileCheck %s
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-01.ll
index 1a118c381a3b61..b6904855547fe0 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-01.ll
@@ -1,3 +1,5 @@
+; Check output of setjmp/longjmp.
+
; RUN: clang -mbackchain -o %t %s
; RUN: %t | FileCheck %s
; CHECK: call foo
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-02.ll
index 627c29469ca3c9..f1aa58d2a2de67 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-02.ll
@@ -1,26 +1,23 @@
-; RUN: clang -o %t %s
-; RUN: %t | FileCheck %s
-; CHECK: setjmp has been called
-; CHECK-NEXT: Calling function foo
-; CHECK-NEXT: Calling longjmp from inside function foo
-; CHECK-NEXT: longjmp has been called
-; CHECK-NEXT: Performing function recover
-; ModuleID = 'builtin-setjmp-longjmp-02.c'
-source_filename = "builtin-setjmp-longjmp-02.c"
+; Test -mbackchain setjmp store jmp_buf
+; Return address in slot 2.
+; Backchain value in slot 3.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
+; RUN: llc < %s | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-backchain-02.c'
+source_filename = "builtin-setjmp-longjmp-backchain-02.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
target triple = "s390x-unknown-linux-gnu"
@buf = dso_local global [20 x ptr] zeroinitializer, align 8
- at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
- at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
- at str.7 = private unnamed_addr constant [23 x i8] c"setjmp has been called\00", align 1
- at str.8 = private unnamed_addr constant [21 x i8] c"Calling function foo\00", align 1
- at str.10 = private unnamed_addr constant [24 x i8] c"longjmp has been called\00", align 1
+ at str = private unnamed_addr constant [9 x i8] c"call foo\00", align 1
+ at str.2 = private unnamed_addr constant [7 x i8] c"return\00", align 1
; Function Attrs: noreturn nounwind
define dso_local void @foo() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
unreachable
}
@@ -28,62 +25,53 @@ entry:
; Function Attrs: noreturn nounwind
declare void @llvm.eh.sjlj.longjmp(ptr) #1
-; Function Attrs: nofree nounwind
-define dso_local void @recover() local_unnamed_addr #2 {
+; Function Attrs: nounwind
+define dso_local noundef signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #2 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
- ret void
-}
+; CHECK: stmg %r6, %r15, 48(%r15)
+; CHECK: lgr %r1, %r15
+; CHECK: aghi %r15, -224
+; CHECK: stg %r1, 0(%r15)
+; CHECK: std %f8, 216(%r15)
+; CHECK: std %f9, 208(%r15)
+; CHECK: std %f10, 200(%r15)
+; CHECK: std %f11, 192(%r15)
+; CHECK: std %f12, 184(%r15)
+; CHECK: std %f13, 176(%r15)
+; CHECK: std %f14, 168(%r15)
+; CHECK: std %f15, 160(%r15)
+; CHECK: larl %r1, buf
+; CHECK: larl %r0, .LBB1_2
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r15, 24(%r1)
+; CHECK: lg %r0, 0(%r15)
+; CHECK: stg %r0, 16(%r1)
-; Function Attrs: noreturn nounwind
-define dso_local noundef signext i32 @main() local_unnamed_addr #0 {
-entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %cmp.not = icmp eq i32 %2, 0
- br i1 %cmp.not, label %if.end, label %if.then
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %tobool.not = icmp eq i32 %0, 0
+ br i1 %tobool.not, label %if.end, label %if.then
if.then: ; preds = %entry
- %puts6 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
- tail call void @recover()
- tail call void @exit(i32 noundef signext 1) #8
- unreachable
+ %puts2 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.2)
+ ret i32 0
if.end: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.7)
- %puts4 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.8)
- %puts.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
unreachable
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #3
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #4
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
-
-; Function Attrs: nofree noreturn nounwind
-declare void @exit(i32 noundef signext) local_unnamed_addr #6
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #4
attributes #0 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #1 = { noreturn nounwind }
-attributes #2 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #3 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #5 = { nounwind }
-attributes #6 = { nofree noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #7 = { nofree nounwind }
-attributes #8 = { cold noreturn nounwind }
+attributes #2 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { nounwind }
+attributes #4 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -91,4 +79,4 @@ attributes #8 = { cold noreturn nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll
index 926048b677cdc0..2c45c5cc089ac7 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll
@@ -1,4 +1,9 @@
-; RUN: llc < %s | FileCheck %s
+; Inducing double register pressure.
+; Test output of setjmp/longjmp with 20 global double variable
+; sum(regsiter pressure).
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+
; ModuleID = 'builtin-setjmp-spills-double-01.c'
source_filename = "builtin-setjmp-spills-double-01.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -25,55 +30,74 @@ target triple = "s390x-unknown-linux-gnu"
@c = dso_local local_unnamed_addr global double 0.000000e+00, align 8
@b = dso_local local_unnamed_addr global double 0.000000e+00, align 8
@a = dso_local local_unnamed_addr global double 0.000000e+00, align 8
- at .str.2 = private unnamed_addr constant [9 x i8] c"a = %lf\0A\00", align 2
- at .str.3 = private unnamed_addr constant [9 x i8] c"b = %lf\0A\00", align 2
- at .str.4 = private unnamed_addr constant [9 x i8] c"c = %lf\0A\00", align 2
- at .str.5 = private unnamed_addr constant [9 x i8] c"d = %lf\0A\00", align 2
- at .str.6 = private unnamed_addr constant [9 x i8] c"e = %lf\0A\00", align 2
- at .str.7 = private unnamed_addr constant [9 x i8] c"f = %lf\0A\00", align 2
- at .str.8 = private unnamed_addr constant [9 x i8] c"g = %lf\0A\00", align 2
- at .str.9 = private unnamed_addr constant [9 x i8] c"h = %lf\0A\00", align 2
- at .str.10 = private unnamed_addr constant [9 x i8] c"i = %lf\0A\00", align 2
- at .str.11 = private unnamed_addr constant [9 x i8] c"j = %lf\0A\00", align 2
- at .str.12 = private unnamed_addr constant [9 x i8] c"k = %lf\0A\00", align 2
- at .str.13 = private unnamed_addr constant [9 x i8] c"l = %lf\0A\00", align 2
- at .str.14 = private unnamed_addr constant [9 x i8] c"m = %lf\0A\00", align 2
- at .str.15 = private unnamed_addr constant [9 x i8] c"n = %lf\0A\00", align 2
- at .str.16 = private unnamed_addr constant [9 x i8] c"o = %lf\0A\00", align 2
- at .str.17 = private unnamed_addr constant [9 x i8] c"p = %lf\0A\00", align 2
- at .str.18 = private unnamed_addr constant [9 x i8] c"q = %lf\0A\00", align 2
- at .str.19 = private unnamed_addr constant [9 x i8] c"r = %lf\0A\00", align 2
- at .str.20 = private unnamed_addr constant [9 x i8] c"s = %lf\0A\00", align 2
- at .str.21 = private unnamed_addr constant [9 x i8] c"t = %lf\0A\00", align 2
- at str = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
- at str.22 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+ at .str.3 = private unnamed_addr constant [9 x i8] c"a = %lf\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [9 x i8] c"b = %lf\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [9 x i8] c"c = %lf\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [9 x i8] c"d = %lf\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"e = %lf\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [9 x i8] c"f = %lf\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [9 x i8] c"g = %lf\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [9 x i8] c"h = %lf\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [9 x i8] c"i = %lf\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [9 x i8] c"j = %lf\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [9 x i8] c"k = %lf\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [9 x i8] c"l = %lf\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [9 x i8] c"m = %lf\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [9 x i8] c"n = %lf\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [9 x i8] c"o = %lf\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [9 x i8] c"p = %lf\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [9 x i8] c"q = %lf\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [9 x i8] c"r = %lf\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [9 x i8] c"s = %lf\0A\00", align 2
+ at .str.22 = private unnamed_addr constant [9 x i8] c"t = %lf\0A\00", align 2
+ at .str.23 = private unnamed_addr constant [12 x i8] c"val is %lf\0A\00", align 2
+ at str = private unnamed_addr constant [8 x i8] c"In func\00", align 1
+ at str.24 = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.25 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
-; Function Attrs: nounwind
-define dso_local double @func() local_unnamed_addr #0 {
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func1() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind
+define dso_local double @func() local_unnamed_addr #3 {
entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
-; CHECK: stmg %r6, %r15, 48(%r15)
-; CHECK: ghi %r15, -224
-; CHECK: std %f8, 216(%r15)
-; CHECK: std %f9, 208(%r15)
-; CHECK: std %f10, 200(%r15)
-; CHECK: std %f11, 192(%r15)
-; CHECK: std %f12, 184(%r15)
-; CHECK: std %f13, 176(%r15)
-; CHECK: std %f14, 168(%r15)
-; CHECK: std %f15, 160(%r15)
-; CHECK: la %r0, 224(%r15)
-; CHECK: stgrl %r0, buf
-; CHECK: stgrl %r15, buf+24
-; CHECK: larl %r1, buf
-; CHECK: larl %r0, .LBB0_3
-; CHECK: stg %r0, 8(%r1)
-; CHECK: stg %r13, 32(%r1)
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %cmp = icmp eq i32 %2, 0
+; CHECK: First time through, all variables are 1
+; CHECK: In func
+; CHECK: Second time through, checking variables:
+; CHECK: a = 1.000000
+; CHECK: b = 1.000000
+; CHECK: c = 1.000000
+; CHECK: d = 1.000000
+; CHECK: e = 1.000000
+; CHECK: f = 1.000000
+; CHECK: g = 1.000000
+; CHECK: h = 1.000000
+; CHECK: i = 1.000000
+; CHECK: j = 1.000000
+; CHECK: k = 1.000000
+; CHECK: l = 1.000000
+; CHECK: m = 1.000000
+; CHECK: n = 1.000000
+; CHECK: o = 1.000000
+; CHECK: p = 1.000000
+; CHECK: q = 1.000000
+; CHECK: r = 1.000000
+; CHECK: s = 1.000000
+; CHECK: t = 1.000000
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
@@ -97,117 +121,116 @@ if.then: ; preds = %entry
store double 1.000000e+00, ptr @c, align 8, !tbaa !4
store double 1.000000e+00, ptr @b, align 8, !tbaa !4
store double 1.000000e+00, ptr @a, align 8, !tbaa !4
- %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
- br label %if.end
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.25)
+ tail call void @func1()
+ unreachable
if.else: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
- %3 = load double, ptr @a, align 8, !tbaa !4
- %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, double noundef %3)
- %4 = load double, ptr @b, align 8, !tbaa !4
- %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, double noundef %4)
- %5 = load double, ptr @c, align 8, !tbaa !4
- %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, double noundef %5)
- %6 = load double, ptr @d, align 8, !tbaa !4
- %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, double noundef %6)
- %7 = load double, ptr @e, align 8, !tbaa !4
- %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, double noundef %7)
- %8 = load double, ptr @f, align 8, !tbaa !4
- %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, double noundef %8)
- %9 = load double, ptr @g, align 8, !tbaa !4
- %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, double noundef %9)
- %10 = load double, ptr @h, align 8, !tbaa !4
- %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, double noundef %10)
- %11 = load double, ptr @i, align 8, !tbaa !4
- %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, double noundef %11)
- %12 = load double, ptr @j, align 8, !tbaa !4
- %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, double noundef %12)
- %13 = load double, ptr @k, align 8, !tbaa !4
- %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, double noundef %13)
- %14 = load double, ptr @l, align 8, !tbaa !4
- %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, double noundef %14)
- %15 = load double, ptr @m, align 8, !tbaa !4
- %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, double noundef %15)
- %16 = load double, ptr @n, align 8, !tbaa !4
- %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, double noundef %16)
- %17 = load double, ptr @o, align 8, !tbaa !4
- %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, double noundef %17)
- %18 = load double, ptr @p, align 8, !tbaa !4
- %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, double noundef %18)
- %19 = load double, ptr @q, align 8, !tbaa !4
- %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, double noundef %19)
- %20 = load double, ptr @r, align 8, !tbaa !4
- %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, double noundef %20)
- %21 = load double, ptr @s, align 8, !tbaa !4
- %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, double noundef %21)
- %22 = load double, ptr @t, align 8, !tbaa !4
- %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, double noundef %22)
- br label %if.end
-
-if.end: ; preds = %if.else, %if.then
- %23 = load double, ptr @a, align 8, !tbaa !4
- %24 = load double, ptr @b, align 8, !tbaa !4
- %add = fadd double %23, %24
- %25 = load double, ptr @c, align 8, !tbaa !4
- %add22 = fadd double %add, %25
- %26 = load double, ptr @d, align 8, !tbaa !4
- %add23 = fadd double %add22, %26
- %27 = load double, ptr @e, align 8, !tbaa !4
- %add24 = fadd double %add23, %27
- %28 = load double, ptr @f, align 8, !tbaa !4
- %add25 = fadd double %add24, %28
- %29 = load double, ptr @g, align 8, !tbaa !4
- %add26 = fadd double %add25, %29
- %30 = load double, ptr @h, align 8, !tbaa !4
- %add27 = fadd double %add26, %30
- %31 = load double, ptr @i, align 8, !tbaa !4
- %add28 = fadd double %add27, %31
- %32 = load double, ptr @j, align 8, !tbaa !4
- %add29 = fadd double %add28, %32
- %33 = load double, ptr @k, align 8, !tbaa !4
- %add30 = fadd double %add29, %33
- %34 = load double, ptr @l, align 8, !tbaa !4
- %add31 = fadd double %add30, %34
- %35 = load double, ptr @m, align 8, !tbaa !4
- %add32 = fadd double %add31, %35
- %36 = load double, ptr @n, align 8, !tbaa !4
- %add33 = fadd double %add32, %36
- %37 = load double, ptr @o, align 8, !tbaa !4
- %add34 = fadd double %add33, %37
- %38 = load double, ptr @p, align 8, !tbaa !4
- %add35 = fadd double %add34, %38
- %39 = load double, ptr @q, align 8, !tbaa !4
- %add36 = fadd double %add35, %39
- %40 = load double, ptr @r, align 8, !tbaa !4
- %add37 = fadd double %add36, %40
- %41 = load double, ptr @s, align 8, !tbaa !4
- %add38 = fadd double %add37, %41
- %42 = load double, ptr @t, align 8, !tbaa !4
- %add39 = fadd double %add38, %42
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.24)
+ %1 = load double, ptr @a, align 8, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, double noundef %1)
+ %2 = load double, ptr @b, align 8, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, double noundef %2)
+ %3 = load double, ptr @c, align 8, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, double noundef %3)
+ %4 = load double, ptr @d, align 8, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, double noundef %4)
+ %5 = load double, ptr @e, align 8, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, double noundef %5)
+ %6 = load double, ptr @f, align 8, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, double noundef %6)
+ %7 = load double, ptr @g, align 8, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, double noundef %7)
+ %8 = load double, ptr @h, align 8, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, double noundef %8)
+ %9 = load double, ptr @i, align 8, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, double noundef %9)
+ %10 = load double, ptr @j, align 8, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, double noundef %10)
+ %11 = load double, ptr @k, align 8, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, double noundef %11)
+ %12 = load double, ptr @l, align 8, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, double noundef %12)
+ %13 = load double, ptr @m, align 8, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, double noundef %13)
+ %14 = load double, ptr @n, align 8, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, double noundef %14)
+ %15 = load double, ptr @o, align 8, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, double noundef %15)
+ %16 = load double, ptr @p, align 8, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, double noundef %16)
+ %17 = load double, ptr @q, align 8, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, double noundef %17)
+ %18 = load double, ptr @r, align 8, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, double noundef %18)
+ %19 = load double, ptr @s, align 8, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, double noundef %19)
+ %20 = load double, ptr @t, align 8, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.22, double noundef %20)
+ %21 = load double, ptr @a, align 8, !tbaa !4
+ %22 = load double, ptr @b, align 8, !tbaa !4
+ %add = fadd double %21, %22
+ %23 = load double, ptr @c, align 8, !tbaa !4
+ %add22 = fadd double %add, %23
+ %24 = load double, ptr @d, align 8, !tbaa !4
+ %add23 = fadd double %add22, %24
+ %25 = load double, ptr @e, align 8, !tbaa !4
+ %add24 = fadd double %add23, %25
+ %26 = load double, ptr @f, align 8, !tbaa !4
+ %add25 = fadd double %add24, %26
+ %27 = load double, ptr @g, align 8, !tbaa !4
+ %add26 = fadd double %add25, %27
+ %28 = load double, ptr @h, align 8, !tbaa !4
+ %add27 = fadd double %add26, %28
+ %29 = load double, ptr @i, align 8, !tbaa !4
+ %add28 = fadd double %add27, %29
+ %30 = load double, ptr @j, align 8, !tbaa !4
+ %add29 = fadd double %add28, %30
+ %31 = load double, ptr @k, align 8, !tbaa !4
+ %add30 = fadd double %add29, %31
+ %32 = load double, ptr @l, align 8, !tbaa !4
+ %add31 = fadd double %add30, %32
+ %33 = load double, ptr @m, align 8, !tbaa !4
+ %add32 = fadd double %add31, %33
+ %34 = load double, ptr @n, align 8, !tbaa !4
+ %add33 = fadd double %add32, %34
+ %35 = load double, ptr @o, align 8, !tbaa !4
+ %add34 = fadd double %add33, %35
+ %36 = load double, ptr @p, align 8, !tbaa !4
+ %add35 = fadd double %add34, %36
+ %37 = load double, ptr @q, align 8, !tbaa !4
+ %add36 = fadd double %add35, %37
+ %38 = load double, ptr @r, align 8, !tbaa !4
+ %add37 = fadd double %add36, %38
+ %39 = load double, ptr @s, align 8, !tbaa !4
+ %add38 = fadd double %add37, %39
+ %40 = load double, ptr @t, align 8, !tbaa !4
+ %add39 = fadd double %add38, %40
ret double %add39
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #1
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #2
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
-; Function Attrs: nofree nounwind
-declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+; CHECK: val is 20.000000
+ %call = tail call double @func()
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.23, double noundef %call)
+ ret i32 0
+}
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #5
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
-attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #3 = { nounwind }
-attributes #4 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #5 = { nofree nounwind }
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -215,7 +238,7 @@ attributes #5 = { nofree nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
!4 = !{!5, !5, i64 0}
!5 = !{!"double", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll
index 3c2fbdc00b599e..2ef58fabe342e3 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll
@@ -1,4 +1,13 @@
+; Simulate register pressure around setjmp call for double precision arguments.
+; Test assembly of funtion call foo in func() in setjmp if and else part.
+; extern foo has 20 argument pointer to double precision.
+; Test setjmp store jmp_buf.
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
; RUN: llc < %s | FileCheck %s
+
; ModuleID = 'builtin-setjmp-spills-double-02.c'
source_filename = "builtin-setjmp-spills-double-02.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -30,10 +39,6 @@ target triple = "s390x-unknown-linux-gnu"
; Function Attrs: nounwind
define dso_local double @func() local_unnamed_addr #0 {
entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
; CHECK: stmg %r6, %r15, 48(%r15)
; CHECK: ghi %r15, -344
; CHECK: std %f8, 336(%r15)
@@ -44,16 +49,13 @@ entry:
; CHECK: std %f13, 296(%r15)
; CHECK: std %f14, 288(%r15)
; CHECK: std %f15, 280(%r15)
-; CHECK: la %r0, 344(%r15)
-; CHECK: stgrl %r0, buf
-; CHECK: stgrl %r15, buf+16
; CHECK: larl %r1, buf
; CHECK: larl %r0, .LBB0_2
; CHECK: stg %r0, 8(%r1)
; CHECK: stg %r15, 24(%r1)
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %cmp = icmp eq i32 %2, 0
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
@@ -81,69 +83,61 @@ if.then: ; preds = %entry
br label %if.end
if.end: ; preds = %entry, %if.then
- tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
- %3 = load double, ptr @a, align 8, !tbaa !4
- %4 = load double, ptr @b, align 8, !tbaa !4
- %add = fadd double %3, %4
- %5 = load double, ptr @c, align 8, !tbaa !4
- %add1 = fadd double %add, %5
- %6 = load double, ptr @d, align 8, !tbaa !4
- %add2 = fadd double %add1, %6
- %7 = load double, ptr @e, align 8, !tbaa !4
- %add3 = fadd double %add2, %7
- %8 = load double, ptr @f, align 8, !tbaa !4
- %add4 = fadd double %add3, %8
- %9 = load double, ptr @g, align 8, !tbaa !4
- %add5 = fadd double %add4, %9
- %10 = load double, ptr @h, align 8, !tbaa !4
- %add6 = fadd double %add5, %10
- %11 = load double, ptr @i, align 8, !tbaa !4
- %add7 = fadd double %add6, %11
- %12 = load double, ptr @j, align 8, !tbaa !4
- %add8 = fadd double %add7, %12
- %13 = load double, ptr @k, align 8, !tbaa !4
- %add9 = fadd double %add8, %13
- %14 = load double, ptr @l, align 8, !tbaa !4
- %add10 = fadd double %add9, %14
- %15 = load double, ptr @m, align 8, !tbaa !4
- %add11 = fadd double %add10, %15
- %16 = load double, ptr @n, align 8, !tbaa !4
- %add12 = fadd double %add11, %16
- %17 = load double, ptr @o, align 8, !tbaa !4
- %add13 = fadd double %add12, %17
- %18 = load double, ptr @p, align 8, !tbaa !4
- %add14 = fadd double %add13, %18
- %19 = load double, ptr @q, align 8, !tbaa !4
- %add15 = fadd double %add14, %19
- %20 = load double, ptr @r, align 8, !tbaa !4
- %add16 = fadd double %add15, %20
- %21 = load double, ptr @s, align 8, !tbaa !4
- %add17 = fadd double %add16, %21
- %22 = load double, ptr @t, align 8, !tbaa !4
- %add18 = fadd double %add17, %22
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
+ %1 = load double, ptr @a, align 8, !tbaa !4
+ %2 = load double, ptr @b, align 8, !tbaa !4
+ %add = fadd double %1, %2
+ %3 = load double, ptr @c, align 8, !tbaa !4
+ %add1 = fadd double %add, %3
+ %4 = load double, ptr @d, align 8, !tbaa !4
+ %add2 = fadd double %add1, %4
+ %5 = load double, ptr @e, align 8, !tbaa !4
+ %add3 = fadd double %add2, %5
+ %6 = load double, ptr @f, align 8, !tbaa !4
+ %add4 = fadd double %add3, %6
+ %7 = load double, ptr @g, align 8, !tbaa !4
+ %add5 = fadd double %add4, %7
+ %8 = load double, ptr @h, align 8, !tbaa !4
+ %add6 = fadd double %add5, %8
+ %9 = load double, ptr @i, align 8, !tbaa !4
+ %add7 = fadd double %add6, %9
+ %10 = load double, ptr @j, align 8, !tbaa !4
+ %add8 = fadd double %add7, %10
+ %11 = load double, ptr @k, align 8, !tbaa !4
+ %add9 = fadd double %add8, %11
+ %12 = load double, ptr @l, align 8, !tbaa !4
+ %add10 = fadd double %add9, %12
+ %13 = load double, ptr @m, align 8, !tbaa !4
+ %add11 = fadd double %add10, %13
+ %14 = load double, ptr @n, align 8, !tbaa !4
+ %add12 = fadd double %add11, %14
+ %15 = load double, ptr @o, align 8, !tbaa !4
+ %add13 = fadd double %add12, %15
+ %16 = load double, ptr @p, align 8, !tbaa !4
+ %add14 = fadd double %add13, %16
+ %17 = load double, ptr @q, align 8, !tbaa !4
+ %add15 = fadd double %add14, %17
+ %18 = load double, ptr @r, align 8, !tbaa !4
+ %add16 = fadd double %add15, %18
+ %19 = load double, ptr @s, align 8, !tbaa !4
+ %add17 = fadd double %add16, %19
+ %20 = load double, ptr @t, align 8, !tbaa !4
+ %add18 = fadd double %add17, %20
ret double %add18
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #1
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #2
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
-declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #4
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #2
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #5
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #3
attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #3 = { nounwind }
-attributes #4 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #5 = { nofree nounwind }
+attributes #1 = { nounwind }
+attributes #2 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll
index 0325a1f8fc874c..2637bda4c67eb5 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll
@@ -1,4 +1,14 @@
+; Simulate register pressure around setjmp call for double precision
+; arguments and return sum of 20 vaiables. It also prints the variables.
+; Test assembly of funtion call foo in func() in setjmp if and else part.
+; extern foo has 20 argument pointer to double precision.
+; Test setjmp store jmp_buf.
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
; RUN: llc < %s | FileCheck %s
+
; ModuleID = 'builtin-setjmp-spills-double-03.c'
source_filename = "builtin-setjmp-spills-double-03.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -51,10 +61,6 @@ target triple = "s390x-unknown-linux-gnu"
; Function Attrs: nounwind
define dso_local double @func() local_unnamed_addr #0 {
entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
; CHECK: stmg %r6, %r15, 48(%r15)
; CHECK: ghi %r15, -344
; CHECK: std %f8, 336(%r15)
@@ -65,15 +71,13 @@ entry:
; CHECK: std %f13, 296(%r15)
; CHECK: std %f14, 288(%r15)
; CHECK: std %f15, 280(%r15)
-; CHECK: la %r0, 344(%r15)
-; CHECK: stgrl %r0, buf
-; CHECK: stgrl %r15, buf+16
; CHECK: larl %r1, buf
; CHECK: larl %r0, .LBB0_3
; CHECK: stg %r0, 8(%r1)
; CHECK: stg %r15, 24(%r1)
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %cmp = icmp eq i32 %2, 0
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
@@ -98,121 +102,113 @@ if.then: ; preds = %entry
store double 1.000000e+00, ptr @b, align 8, !tbaa !4
store double 1.000000e+00, ptr @a, align 8, !tbaa !4
%puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
- tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
br label %if.end
if.else: ; preds = %entry
- tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
%puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
- %3 = load double, ptr @a, align 8, !tbaa !4
- %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, double noundef %3)
- %4 = load double, ptr @b, align 8, !tbaa !4
- %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, double noundef %4)
- %5 = load double, ptr @c, align 8, !tbaa !4
- %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, double noundef %5)
- %6 = load double, ptr @d, align 8, !tbaa !4
- %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, double noundef %6)
- %7 = load double, ptr @e, align 8, !tbaa !4
- %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, double noundef %7)
- %8 = load double, ptr @f, align 8, !tbaa !4
- %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, double noundef %8)
- %9 = load double, ptr @g, align 8, !tbaa !4
- %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, double noundef %9)
- %10 = load double, ptr @h, align 8, !tbaa !4
- %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, double noundef %10)
- %11 = load double, ptr @i, align 8, !tbaa !4
- %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, double noundef %11)
- %12 = load double, ptr @j, align 8, !tbaa !4
- %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, double noundef %12)
- %13 = load double, ptr @k, align 8, !tbaa !4
- %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, double noundef %13)
- %14 = load double, ptr @l, align 8, !tbaa !4
- %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, double noundef %14)
- %15 = load double, ptr @m, align 8, !tbaa !4
- %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, double noundef %15)
- %16 = load double, ptr @n, align 8, !tbaa !4
- %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, double noundef %16)
- %17 = load double, ptr @o, align 8, !tbaa !4
- %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, double noundef %17)
- %18 = load double, ptr @p, align 8, !tbaa !4
- %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, double noundef %18)
- %19 = load double, ptr @q, align 8, !tbaa !4
- %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, double noundef %19)
- %20 = load double, ptr @r, align 8, !tbaa !4
- %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, double noundef %20)
- %21 = load double, ptr @s, align 8, !tbaa !4
- %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, double noundef %21)
- %22 = load double, ptr @t, align 8, !tbaa !4
- %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, double noundef %22)
+ %1 = load double, ptr @a, align 8, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, double noundef %1)
+ %2 = load double, ptr @b, align 8, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, double noundef %2)
+ %3 = load double, ptr @c, align 8, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, double noundef %3)
+ %4 = load double, ptr @d, align 8, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, double noundef %4)
+ %5 = load double, ptr @e, align 8, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, double noundef %5)
+ %6 = load double, ptr @f, align 8, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, double noundef %6)
+ %7 = load double, ptr @g, align 8, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, double noundef %7)
+ %8 = load double, ptr @h, align 8, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, double noundef %8)
+ %9 = load double, ptr @i, align 8, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, double noundef %9)
+ %10 = load double, ptr @j, align 8, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, double noundef %10)
+ %11 = load double, ptr @k, align 8, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, double noundef %11)
+ %12 = load double, ptr @l, align 8, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, double noundef %12)
+ %13 = load double, ptr @m, align 8, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, double noundef %13)
+ %14 = load double, ptr @n, align 8, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, double noundef %14)
+ %15 = load double, ptr @o, align 8, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, double noundef %15)
+ %16 = load double, ptr @p, align 8, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, double noundef %16)
+ %17 = load double, ptr @q, align 8, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, double noundef %17)
+ %18 = load double, ptr @r, align 8, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, double noundef %18)
+ %19 = load double, ptr @s, align 8, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, double noundef %19)
+ %20 = load double, ptr @t, align 8, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, double noundef %20)
br label %if.end
if.end: ; preds = %if.else, %if.then
- %23 = load double, ptr @a, align 8, !tbaa !4
- %24 = load double, ptr @b, align 8, !tbaa !4
- %add = fadd double %23, %24
- %25 = load double, ptr @c, align 8, !tbaa !4
- %add22 = fadd double %add, %25
- %26 = load double, ptr @d, align 8, !tbaa !4
- %add23 = fadd double %add22, %26
- %27 = load double, ptr @e, align 8, !tbaa !4
- %add24 = fadd double %add23, %27
- %28 = load double, ptr @f, align 8, !tbaa !4
- %add25 = fadd double %add24, %28
- %29 = load double, ptr @g, align 8, !tbaa !4
- %add26 = fadd double %add25, %29
- %30 = load double, ptr @h, align 8, !tbaa !4
- %add27 = fadd double %add26, %30
- %31 = load double, ptr @i, align 8, !tbaa !4
- %add28 = fadd double %add27, %31
- %32 = load double, ptr @j, align 8, !tbaa !4
- %add29 = fadd double %add28, %32
- %33 = load double, ptr @k, align 8, !tbaa !4
- %add30 = fadd double %add29, %33
- %34 = load double, ptr @l, align 8, !tbaa !4
- %add31 = fadd double %add30, %34
- %35 = load double, ptr @m, align 8, !tbaa !4
- %add32 = fadd double %add31, %35
- %36 = load double, ptr @n, align 8, !tbaa !4
- %add33 = fadd double %add32, %36
- %37 = load double, ptr @o, align 8, !tbaa !4
- %add34 = fadd double %add33, %37
- %38 = load double, ptr @p, align 8, !tbaa !4
- %add35 = fadd double %add34, %38
- %39 = load double, ptr @q, align 8, !tbaa !4
- %add36 = fadd double %add35, %39
- %40 = load double, ptr @r, align 8, !tbaa !4
- %add37 = fadd double %add36, %40
- %41 = load double, ptr @s, align 8, !tbaa !4
- %add38 = fadd double %add37, %41
- %42 = load double, ptr @t, align 8, !tbaa !4
- %add39 = fadd double %add38, %42
+ %21 = load double, ptr @a, align 8, !tbaa !4
+ %22 = load double, ptr @b, align 8, !tbaa !4
+ %add = fadd double %21, %22
+ %23 = load double, ptr @c, align 8, !tbaa !4
+ %add22 = fadd double %add, %23
+ %24 = load double, ptr @d, align 8, !tbaa !4
+ %add23 = fadd double %add22, %24
+ %25 = load double, ptr @e, align 8, !tbaa !4
+ %add24 = fadd double %add23, %25
+ %26 = load double, ptr @f, align 8, !tbaa !4
+ %add25 = fadd double %add24, %26
+ %27 = load double, ptr @g, align 8, !tbaa !4
+ %add26 = fadd double %add25, %27
+ %28 = load double, ptr @h, align 8, !tbaa !4
+ %add27 = fadd double %add26, %28
+ %29 = load double, ptr @i, align 8, !tbaa !4
+ %add28 = fadd double %add27, %29
+ %30 = load double, ptr @j, align 8, !tbaa !4
+ %add29 = fadd double %add28, %30
+ %31 = load double, ptr @k, align 8, !tbaa !4
+ %add30 = fadd double %add29, %31
+ %32 = load double, ptr @l, align 8, !tbaa !4
+ %add31 = fadd double %add30, %32
+ %33 = load double, ptr @m, align 8, !tbaa !4
+ %add32 = fadd double %add31, %33
+ %34 = load double, ptr @n, align 8, !tbaa !4
+ %add33 = fadd double %add32, %34
+ %35 = load double, ptr @o, align 8, !tbaa !4
+ %add34 = fadd double %add33, %35
+ %36 = load double, ptr @p, align 8, !tbaa !4
+ %add35 = fadd double %add34, %36
+ %37 = load double, ptr @q, align 8, !tbaa !4
+ %add36 = fadd double %add35, %37
+ %38 = load double, ptr @r, align 8, !tbaa !4
+ %add37 = fadd double %add36, %38
+ %39 = load double, ptr @s, align 8, !tbaa !4
+ %add38 = fadd double %add37, %39
+ %40 = load double, ptr @t, align 8, !tbaa !4
+ %add39 = fadd double %add38, %40
ret double %add39
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #1
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #2
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
; Function Attrs: nofree nounwind
-declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #2
-declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #5
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #3
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #4
attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #3 = { nounwind }
-attributes #4 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #5 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #6 = { nofree nounwind }
+attributes #1 = { nounwind }
+attributes #2 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll
index a9d026912da1af..0a4d115f6d4f55 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll
@@ -1,4 +1,9 @@
-; RUN: llc < %s | FileCheck %s
+; Inducing integer register pressure.
+; Test output of setjmp/longjmp with 20 global int variable sum(regsiter pressure).
+; RUN: clang -o %t %s
+; RUN: %t | FileCheck %s
+
+
; ModuleID = 'builtin-setjmp-spills-int-01.c'
source_filename = "builtin-setjmp-spills-int-01.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -25,55 +30,72 @@ target triple = "s390x-unknown-linux-gnu"
@c = dso_local local_unnamed_addr global i32 0, align 4
@b = dso_local local_unnamed_addr global i32 0, align 4
@a = dso_local local_unnamed_addr global i32 0, align 4
- at .str.2 = private unnamed_addr constant [8 x i8] c"a = %d\0A\00", align 2
- at .str.3 = private unnamed_addr constant [8 x i8] c"b = %d\0A\00", align 2
- at .str.4 = private unnamed_addr constant [8 x i8] c"c = %d\0A\00", align 2
- at .str.5 = private unnamed_addr constant [8 x i8] c"d = %d\0A\00", align 2
- at .str.6 = private unnamed_addr constant [8 x i8] c"e = %d\0A\00", align 2
- at .str.7 = private unnamed_addr constant [8 x i8] c"f = %d\0A\00", align 2
- at .str.8 = private unnamed_addr constant [8 x i8] c"g = %d\0A\00", align 2
- at .str.9 = private unnamed_addr constant [8 x i8] c"h = %d\0A\00", align 2
- at .str.10 = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 2
- at .str.11 = private unnamed_addr constant [8 x i8] c"j = %d\0A\00", align 2
- at .str.12 = private unnamed_addr constant [8 x i8] c"k = %d\0A\00", align 2
- at .str.13 = private unnamed_addr constant [8 x i8] c"l = %d\0A\00", align 2
- at .str.14 = private unnamed_addr constant [8 x i8] c"m = %d\0A\00", align 2
- at .str.15 = private unnamed_addr constant [8 x i8] c"n = %d\0A\00", align 2
- at .str.16 = private unnamed_addr constant [8 x i8] c"o = %d\0A\00", align 2
- at .str.17 = private unnamed_addr constant [8 x i8] c"p = %d\0A\00", align 2
- at .str.18 = private unnamed_addr constant [8 x i8] c"q = %d\0A\00", align 2
- at .str.19 = private unnamed_addr constant [8 x i8] c"r = %d\0A\00", align 2
- at .str.20 = private unnamed_addr constant [8 x i8] c"s = %d\0A\00", align 2
- at .str.21 = private unnamed_addr constant [8 x i8] c"t = %d\0A\00", align 2
- at str = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
- at str.22 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
+ at .str.3 = private unnamed_addr constant [8 x i8] c"a = %d\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [8 x i8] c"b = %d\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [8 x i8] c"c = %d\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [8 x i8] c"d = %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [8 x i8] c"e = %d\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [8 x i8] c"f = %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [8 x i8] c"g = %d\0A\00", align 2
+ at .str.10 = private unnamed_addr constant [8 x i8] c"h = %d\0A\00", align 2
+ at .str.11 = private unnamed_addr constant [8 x i8] c"i = %d\0A\00", align 2
+ at .str.12 = private unnamed_addr constant [8 x i8] c"j = %d\0A\00", align 2
+ at .str.13 = private unnamed_addr constant [8 x i8] c"k = %d\0A\00", align 2
+ at .str.14 = private unnamed_addr constant [8 x i8] c"l = %d\0A\00", align 2
+ at .str.15 = private unnamed_addr constant [8 x i8] c"m = %d\0A\00", align 2
+ at .str.16 = private unnamed_addr constant [8 x i8] c"n = %d\0A\00", align 2
+ at .str.17 = private unnamed_addr constant [8 x i8] c"o = %d\0A\00", align 2
+ at .str.18 = private unnamed_addr constant [8 x i8] c"p = %d\0A\00", align 2
+ at .str.19 = private unnamed_addr constant [8 x i8] c"q = %d\0A\00", align 2
+ at .str.20 = private unnamed_addr constant [8 x i8] c"r = %d\0A\00", align 2
+ at .str.21 = private unnamed_addr constant [8 x i8] c"s = %d\0A\00", align 2
+ at .str.22 = private unnamed_addr constant [8 x i8] c"t = %d\0A\00", align 2
+ at .str.23 = private unnamed_addr constant [11 x i8] c"val is %d\0A\00", align 2
+ at str = private unnamed_addr constant [8 x i8] c"In func\00", align 1
+ at str.24 = private unnamed_addr constant [41 x i8] c"Second time through, checking variables:\00", align 1
+ at str.25 = private unnamed_addr constant [40 x i8] c"First time through, all variables are 1\00", align 1
-; Function Attrs: nounwind
-define dso_local signext i32 @func() local_unnamed_addr #0 {
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func1() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind
+define dso_local signext i32 @func() local_unnamed_addr #3 {
entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 24), align 8
-; CHECK: stmg %r6, %r15, 48(%r15)
-; CHECK: ghi %r15, -224
-; CHECK: std %f8, 216(%r15)
-; CHECK: std %f9, 208(%r15)
-; CHECK: std %f10, 200(%r15)
-; CHECK: std %f11, 192(%r15)
-; CHECK: std %f12, 184(%r15)
-; CHECK: std %f13, 176(%r15)
-; CHECK: std %f14, 168(%r15)
-; CHECK: std %f15, 160(%r15)
-; CHECK: la %r0, 224(%r15)
-; CHECK: stgrl %r0, buf
-; CHECK: stgrl %r15, buf+24
-; CHECK: larl %r1, buf
-; CHECK: larl %r0, .LBB0_3
-; CHECK: stg %r0, 8(%r1)
-; CHECK: stg %r13, 32(%r1)
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %cmp = icmp eq i32 %2, 0
+; CHECK: Second time through, checking variables:
+; CHECK: a = 1
+; CHECK: b = 1
+; CHECK: c = 1
+; CHECK: d = 1
+; CHECK: e = 1
+; CHECK: f = 1
+; CHECK: g = 1
+; CHECK: h = 1
+; CHECK: i = 1
+; CHECK: j = 1
+; CHECK: k = 1
+; CHECK: l = 1
+; CHECK: m = 1
+; CHECK: n = 1
+; CHECK: o = 1
+; CHECK: p = 1
+; CHECK: q = 1
+; CHECK: r = 1
+; CHECK: s = 1
+; CHECK: t = 1
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
@@ -97,117 +119,116 @@ if.then: ; preds = %entry
store i32 1, ptr @c, align 4, !tbaa !4
store i32 1, ptr @b, align 4, !tbaa !4
store i32 1, ptr @a, align 4, !tbaa !4
- %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
- br label %if.end
+ %puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.25)
+ tail call void @func1()
+ unreachable
if.else: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
- %3 = load i32, ptr @a, align 4, !tbaa !4
- %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %3)
- %4 = load i32, ptr @b, align 4, !tbaa !4
- %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %4)
- %5 = load i32, ptr @c, align 4, !tbaa !4
- %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %5)
- %6 = load i32, ptr @d, align 4, !tbaa !4
- %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, i32 noundef signext %6)
- %7 = load i32, ptr @e, align 4, !tbaa !4
- %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %7)
- %8 = load i32, ptr @f, align 4, !tbaa !4
- %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %8)
- %9 = load i32, ptr @g, align 4, !tbaa !4
- %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %9)
- %10 = load i32, ptr @h, align 4, !tbaa !4
- %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %10)
- %11 = load i32, ptr @i, align 4, !tbaa !4
- %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, i32 noundef signext %11)
- %12 = load i32, ptr @j, align 4, !tbaa !4
- %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %12)
- %13 = load i32, ptr @k, align 4, !tbaa !4
- %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, i32 noundef signext %13)
- %14 = load i32, ptr @l, align 4, !tbaa !4
- %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %14)
- %15 = load i32, ptr @m, align 4, !tbaa !4
- %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, i32 noundef signext %15)
- %16 = load i32, ptr @n, align 4, !tbaa !4
- %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, i32 noundef signext %16)
- %17 = load i32, ptr @o, align 4, !tbaa !4
- %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, i32 noundef signext %17)
- %18 = load i32, ptr @p, align 4, !tbaa !4
- %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, i32 noundef signext %18)
- %19 = load i32, ptr @q, align 4, !tbaa !4
- %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, i32 noundef signext %19)
- %20 = load i32, ptr @r, align 4, !tbaa !4
- %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, i32 noundef signext %20)
- %21 = load i32, ptr @s, align 4, !tbaa !4
- %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, i32 noundef signext %21)
- %22 = load i32, ptr @t, align 4, !tbaa !4
- %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, i32 noundef signext %22)
- br label %if.end
-
-if.end: ; preds = %if.else, %if.then
- %23 = load i32, ptr @a, align 4, !tbaa !4
- %24 = load i32, ptr @b, align 4, !tbaa !4
- %add = add nsw i32 %24, %23
- %25 = load i32, ptr @c, align 4, !tbaa !4
- %add22 = add nsw i32 %add, %25
- %26 = load i32, ptr @d, align 4, !tbaa !4
- %add23 = add nsw i32 %add22, %26
- %27 = load i32, ptr @e, align 4, !tbaa !4
- %add24 = add nsw i32 %add23, %27
- %28 = load i32, ptr @f, align 4, !tbaa !4
- %add25 = add nsw i32 %add24, %28
- %29 = load i32, ptr @g, align 4, !tbaa !4
- %add26 = add nsw i32 %add25, %29
- %30 = load i32, ptr @h, align 4, !tbaa !4
- %add27 = add nsw i32 %add26, %30
- %31 = load i32, ptr @i, align 4, !tbaa !4
- %add28 = add nsw i32 %add27, %31
- %32 = load i32, ptr @j, align 4, !tbaa !4
- %add29 = add nsw i32 %add28, %32
- %33 = load i32, ptr @k, align 4, !tbaa !4
- %add30 = add nsw i32 %add29, %33
- %34 = load i32, ptr @l, align 4, !tbaa !4
- %add31 = add nsw i32 %add30, %34
- %35 = load i32, ptr @m, align 4, !tbaa !4
- %add32 = add nsw i32 %add31, %35
- %36 = load i32, ptr @n, align 4, !tbaa !4
- %add33 = add nsw i32 %add32, %36
- %37 = load i32, ptr @o, align 4, !tbaa !4
- %add34 = add nsw i32 %add33, %37
- %38 = load i32, ptr @p, align 4, !tbaa !4
- %add35 = add nsw i32 %add34, %38
- %39 = load i32, ptr @q, align 4, !tbaa !4
- %add36 = add nsw i32 %add35, %39
- %40 = load i32, ptr @r, align 4, !tbaa !4
- %add37 = add nsw i32 %add36, %40
- %41 = load i32, ptr @s, align 4, !tbaa !4
- %add38 = add nsw i32 %add37, %41
- %42 = load i32, ptr @t, align 4, !tbaa !4
- %add39 = add nsw i32 %add38, %42
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.24)
+ %1 = load i32, ptr @a, align 4, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %1)
+ %2 = load i32, ptr @b, align 4, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %2)
+ %3 = load i32, ptr @c, align 4, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, i32 noundef signext %3)
+ %4 = load i32, ptr @d, align 4, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %4)
+ %5 = load i32, ptr @e, align 4, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %5)
+ %6 = load i32, ptr @f, align 4, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %6)
+ %7 = load i32, ptr @g, align 4, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %7)
+ %8 = load i32, ptr @h, align 4, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, i32 noundef signext %8)
+ %9 = load i32, ptr @i, align 4, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %9)
+ %10 = load i32, ptr @j, align 4, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, i32 noundef signext %10)
+ %11 = load i32, ptr @k, align 4, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %11)
+ %12 = load i32, ptr @l, align 4, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, i32 noundef signext %12)
+ %13 = load i32, ptr @m, align 4, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, i32 noundef signext %13)
+ %14 = load i32, ptr @n, align 4, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, i32 noundef signext %14)
+ %15 = load i32, ptr @o, align 4, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, i32 noundef signext %15)
+ %16 = load i32, ptr @p, align 4, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, i32 noundef signext %16)
+ %17 = load i32, ptr @q, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, i32 noundef signext %17)
+ %18 = load i32, ptr @r, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, i32 noundef signext %18)
+ %19 = load i32, ptr @s, align 4, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, i32 noundef signext %19)
+ %20 = load i32, ptr @t, align 4, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.22, i32 noundef signext %20)
+ %21 = load i32, ptr @a, align 4, !tbaa !4
+ %22 = load i32, ptr @b, align 4, !tbaa !4
+ %add = add nsw i32 %22, %21
+ %23 = load i32, ptr @c, align 4, !tbaa !4
+ %add22 = add nsw i32 %add, %23
+ %24 = load i32, ptr @d, align 4, !tbaa !4
+ %add23 = add nsw i32 %add22, %24
+ %25 = load i32, ptr @e, align 4, !tbaa !4
+ %add24 = add nsw i32 %add23, %25
+ %26 = load i32, ptr @f, align 4, !tbaa !4
+ %add25 = add nsw i32 %add24, %26
+ %27 = load i32, ptr @g, align 4, !tbaa !4
+ %add26 = add nsw i32 %add25, %27
+ %28 = load i32, ptr @h, align 4, !tbaa !4
+ %add27 = add nsw i32 %add26, %28
+ %29 = load i32, ptr @i, align 4, !tbaa !4
+ %add28 = add nsw i32 %add27, %29
+ %30 = load i32, ptr @j, align 4, !tbaa !4
+ %add29 = add nsw i32 %add28, %30
+ %31 = load i32, ptr @k, align 4, !tbaa !4
+ %add30 = add nsw i32 %add29, %31
+ %32 = load i32, ptr @l, align 4, !tbaa !4
+ %add31 = add nsw i32 %add30, %32
+ %33 = load i32, ptr @m, align 4, !tbaa !4
+ %add32 = add nsw i32 %add31, %33
+ %34 = load i32, ptr @n, align 4, !tbaa !4
+ %add33 = add nsw i32 %add32, %34
+ %35 = load i32, ptr @o, align 4, !tbaa !4
+ %add34 = add nsw i32 %add33, %35
+ %36 = load i32, ptr @p, align 4, !tbaa !4
+ %add35 = add nsw i32 %add34, %36
+ %37 = load i32, ptr @q, align 4, !tbaa !4
+ %add36 = add nsw i32 %add35, %37
+ %38 = load i32, ptr @r, align 4, !tbaa !4
+ %add37 = add nsw i32 %add36, %38
+ %39 = load i32, ptr @s, align 4, !tbaa !4
+ %add38 = add nsw i32 %add37, %39
+ %40 = load i32, ptr @t, align 4, !tbaa !4
+ %add39 = add nsw i32 %add38, %40
ret i32 %add39
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #1
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #2
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
-; Function Attrs: nofree nounwind
-declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+; CHECK: val is 20
+ %call = tail call signext i32 @func()
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.23, i32 noundef signext %call)
+ ret i32 0
+}
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #5
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
-attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #3 = { nounwind }
-attributes #4 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #5 = { nofree nounwind }
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -215,7 +236,7 @@ attributes #5 = { nofree nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 19f04e908667aade0efe2de9ae705baaf68c0ce2)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
!4 = !{!5, !5, i64 0}
!5 = !{!"int", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll
index 40a4794db39da0..3e8bfe81d083b9 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll
@@ -1,4 +1,13 @@
+; Simulate register pressure around setjmp call for integer arguments.
+; Test assembly of funtion call foo in func() in setjmp if and else part.
+; extern foo has 20 argument pointer to int.
+; Test setjmp store jmp_buf.
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
; RUN: llc < %s | FileCheck %s
+
; ModuleID = 'builtin-setjmp-spills-int-02.c'
source_filename = "builtin-setjmp-spills-int-02.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -30,10 +39,6 @@ target triple = "s390x-unknown-linux-gnu"
; Function Attrs: nounwind
define dso_local signext i32 @func() local_unnamed_addr #0 {
entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
; CHECK: stmg %r6, %r15, 48(%r15)
; CHECK: ghi %r15, -344
; CHECK: std %f8, 336(%r15)
@@ -44,15 +49,12 @@ entry:
; CHECK: std %f13, 296(%r15)
; CHECK: std %f14, 288(%r15)
; CHECK: std %f15, 280(%r15)
-; CHECK: la %r0, 344(%r15)
-; CHECK: stgrl %r0, buf
-; CHECK: stgrl %r15, buf+16
; CHECK: larl %r1, buf
; CHECK: larl %r0, .LBB0_2
; CHECK: stg %r0, 8(%r1)
; CHECK: stg %r15, 24(%r1)
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %cmp = icmp eq i32 %2, 0
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
@@ -80,69 +82,61 @@ if.then: ; preds = %entry
br label %if.end
if.end: ; preds = %entry, %if.then
- tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
- %3 = load i32, ptr @a, align 4, !tbaa !4
- %4 = load i32, ptr @b, align 4, !tbaa !4
- %add = add nsw i32 %4, %3
- %5 = load i32, ptr @c, align 4, !tbaa !4
- %add1 = add nsw i32 %add, %5
- %6 = load i32, ptr @d, align 4, !tbaa !4
- %add2 = add nsw i32 %add1, %6
- %7 = load i32, ptr @e, align 4, !tbaa !4
- %add3 = add nsw i32 %add2, %7
- %8 = load i32, ptr @f, align 4, !tbaa !4
- %add4 = add nsw i32 %add3, %8
- %9 = load i32, ptr @g, align 4, !tbaa !4
- %add5 = add nsw i32 %add4, %9
- %10 = load i32, ptr @h, align 4, !tbaa !4
- %add6 = add nsw i32 %add5, %10
- %11 = load i32, ptr @i, align 4, !tbaa !4
- %add7 = add nsw i32 %add6, %11
- %12 = load i32, ptr @j, align 4, !tbaa !4
- %add8 = add nsw i32 %add7, %12
- %13 = load i32, ptr @k, align 4, !tbaa !4
- %add9 = add nsw i32 %add8, %13
- %14 = load i32, ptr @l, align 4, !tbaa !4
- %add10 = add nsw i32 %add9, %14
- %15 = load i32, ptr @m, align 4, !tbaa !4
- %add11 = add nsw i32 %add10, %15
- %16 = load i32, ptr @n, align 4, !tbaa !4
- %add12 = add nsw i32 %add11, %16
- %17 = load i32, ptr @o, align 4, !tbaa !4
- %add13 = add nsw i32 %add12, %17
- %18 = load i32, ptr @p, align 4, !tbaa !4
- %add14 = add nsw i32 %add13, %18
- %19 = load i32, ptr @q, align 4, !tbaa !4
- %add15 = add nsw i32 %add14, %19
- %20 = load i32, ptr @r, align 4, !tbaa !4
- %add16 = add nsw i32 %add15, %20
- %21 = load i32, ptr @s, align 4, !tbaa !4
- %add17 = add nsw i32 %add16, %21
- %22 = load i32, ptr @t, align 4, !tbaa !4
- %add18 = add nsw i32 %add17, %22
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
+ %1 = load i32, ptr @a, align 4, !tbaa !4
+ %2 = load i32, ptr @b, align 4, !tbaa !4
+ %add = add nsw i32 %2, %1
+ %3 = load i32, ptr @c, align 4, !tbaa !4
+ %add1 = add nsw i32 %add, %3
+ %4 = load i32, ptr @d, align 4, !tbaa !4
+ %add2 = add nsw i32 %add1, %4
+ %5 = load i32, ptr @e, align 4, !tbaa !4
+ %add3 = add nsw i32 %add2, %5
+ %6 = load i32, ptr @f, align 4, !tbaa !4
+ %add4 = add nsw i32 %add3, %6
+ %7 = load i32, ptr @g, align 4, !tbaa !4
+ %add5 = add nsw i32 %add4, %7
+ %8 = load i32, ptr @h, align 4, !tbaa !4
+ %add6 = add nsw i32 %add5, %8
+ %9 = load i32, ptr @i, align 4, !tbaa !4
+ %add7 = add nsw i32 %add6, %9
+ %10 = load i32, ptr @j, align 4, !tbaa !4
+ %add8 = add nsw i32 %add7, %10
+ %11 = load i32, ptr @k, align 4, !tbaa !4
+ %add9 = add nsw i32 %add8, %11
+ %12 = load i32, ptr @l, align 4, !tbaa !4
+ %add10 = add nsw i32 %add9, %12
+ %13 = load i32, ptr @m, align 4, !tbaa !4
+ %add11 = add nsw i32 %add10, %13
+ %14 = load i32, ptr @n, align 4, !tbaa !4
+ %add12 = add nsw i32 %add11, %14
+ %15 = load i32, ptr @o, align 4, !tbaa !4
+ %add13 = add nsw i32 %add12, %15
+ %16 = load i32, ptr @p, align 4, !tbaa !4
+ %add14 = add nsw i32 %add13, %16
+ %17 = load i32, ptr @q, align 4, !tbaa !4
+ %add15 = add nsw i32 %add14, %17
+ %18 = load i32, ptr @r, align 4, !tbaa !4
+ %add16 = add nsw i32 %add15, %18
+ %19 = load i32, ptr @s, align 4, !tbaa !4
+ %add17 = add nsw i32 %add16, %19
+ %20 = load i32, ptr @t, align 4, !tbaa !4
+ %add18 = add nsw i32 %add17, %20
ret i32 %add18
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #1
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #2
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
-declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #4
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #2
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #5
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #3
attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #3 = { nounwind }
-attributes #4 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #5 = { nofree nounwind }
+attributes #1 = { nounwind }
+attributes #2 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll
index f0ae742c6e45d5..b84e9a3fc61dd5 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll
@@ -1,4 +1,14 @@
+; Simulate register pressure around setjmp call for integer arguments and
+; return sum of 20 vaiables. It also prints the variables.
+; Test assembly of funtion call foo in func() in setjmp if and else part.
+; extern foo has 20 argument pointer to int.
+; Test setjmp store jmp_buf.
+; Return address in slot 2.
+; Stack Pointer in slot 4.
+; Clobber %r6-%r15, %f8-%f15.
+
; RUN: llc < %s | FileCheck %s
+
; ModuleID = 'builtin-setjmp-spills-int-03.c'
source_filename = "builtin-setjmp-spills-int-03.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
@@ -51,10 +61,6 @@ target triple = "s390x-unknown-linux-gnu"
; Function Attrs: nounwind
define dso_local signext i32 @func() local_unnamed_addr #0 {
entry:
- %0 = tail call ptr @llvm.frameaddress.p0(i32 0)
- store ptr %0, ptr @buf, align 8
- %1 = tail call ptr @llvm.stacksave.p0()
- store ptr %1, ptr getelementptr inbounds (i8, ptr @buf, i64 16), align 8
; CHECK: stmg %r6, %r15, 48(%r15)
; CHECK: ghi %r15, -344
; CHECK: std %f8, 336(%r15)
@@ -65,15 +71,12 @@ entry:
; CHECK: std %f13, 296(%r15)
; CHECK: std %f14, 288(%r15)
; CHECK: std %f15, 280(%r15)
-; CHECK: la %r0, 344(%r15)
-; CHECK: stgrl %r0, buf
-; CHECK: stgrl %r15, buf+16
; CHECK: larl %r1, buf
; CHECK: larl %r0, .LBB0_3
; CHECK: stg %r0, 8(%r1)
; CHECK: stg %r15, 24(%r1)
- %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %cmp = icmp eq i32 %2, 0
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
@@ -98,121 +101,113 @@ if.then: ; preds = %entry
store i32 1, ptr @b, align 4, !tbaa !4
store i32 1, ptr @a, align 4, !tbaa !4
%puts40 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.22)
- tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
br label %if.end
if.else: ; preds = %entry
- tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #3
+ tail call void @foo(ptr noundef nonnull @a, ptr noundef nonnull @b, ptr noundef nonnull @c, ptr noundef nonnull @d, ptr noundef nonnull @e, ptr noundef nonnull @f, ptr noundef nonnull @g, ptr noundef nonnull @h, ptr noundef nonnull @i, ptr noundef nonnull @j, ptr noundef nonnull @k, ptr noundef nonnull @l, ptr noundef nonnull @m, ptr noundef nonnull @n, ptr noundef nonnull @o, ptr noundef nonnull @p, ptr noundef nonnull @q, ptr noundef nonnull @r, ptr noundef nonnull @s, ptr noundef nonnull @t) #1
%puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
- %3 = load i32, ptr @a, align 4, !tbaa !4
- %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %3)
- %4 = load i32, ptr @b, align 4, !tbaa !4
- %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %4)
- %5 = load i32, ptr @c, align 4, !tbaa !4
- %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %5)
- %6 = load i32, ptr @d, align 4, !tbaa !4
- %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, i32 noundef signext %6)
- %7 = load i32, ptr @e, align 4, !tbaa !4
- %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %7)
- %8 = load i32, ptr @f, align 4, !tbaa !4
- %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %8)
- %9 = load i32, ptr @g, align 4, !tbaa !4
- %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %9)
- %10 = load i32, ptr @h, align 4, !tbaa !4
- %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %10)
- %11 = load i32, ptr @i, align 4, !tbaa !4
- %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, i32 noundef signext %11)
- %12 = load i32, ptr @j, align 4, !tbaa !4
- %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %12)
- %13 = load i32, ptr @k, align 4, !tbaa !4
- %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, i32 noundef signext %13)
- %14 = load i32, ptr @l, align 4, !tbaa !4
- %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %14)
- %15 = load i32, ptr @m, align 4, !tbaa !4
- %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, i32 noundef signext %15)
- %16 = load i32, ptr @n, align 4, !tbaa !4
- %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, i32 noundef signext %16)
- %17 = load i32, ptr @o, align 4, !tbaa !4
- %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, i32 noundef signext %17)
- %18 = load i32, ptr @p, align 4, !tbaa !4
- %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, i32 noundef signext %18)
- %19 = load i32, ptr @q, align 4, !tbaa !4
- %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, i32 noundef signext %19)
- %20 = load i32, ptr @r, align 4, !tbaa !4
- %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, i32 noundef signext %20)
- %21 = load i32, ptr @s, align 4, !tbaa !4
- %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, i32 noundef signext %21)
- %22 = load i32, ptr @t, align 4, !tbaa !4
- %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, i32 noundef signext %22)
+ %1 = load i32, ptr @a, align 4, !tbaa !4
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %1)
+ %2 = load i32, ptr @b, align 4, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %2)
+ %3 = load i32, ptr @c, align 4, !tbaa !4
+ %call4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %3)
+ %4 = load i32, ptr @d, align 4, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.5, i32 noundef signext %4)
+ %5 = load i32, ptr @e, align 4, !tbaa !4
+ %call6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %5)
+ %6 = load i32, ptr @f, align 4, !tbaa !4
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %6)
+ %7 = load i32, ptr @g, align 4, !tbaa !4
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %7)
+ %8 = load i32, ptr @h, align 4, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %8)
+ %9 = load i32, ptr @i, align 4, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.10, i32 noundef signext %9)
+ %10 = load i32, ptr @j, align 4, !tbaa !4
+ %call11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %10)
+ %11 = load i32, ptr @k, align 4, !tbaa !4
+ %call12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.12, i32 noundef signext %11)
+ %12 = load i32, ptr @l, align 4, !tbaa !4
+ %call13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %12)
+ %13 = load i32, ptr @m, align 4, !tbaa !4
+ %call14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.14, i32 noundef signext %13)
+ %14 = load i32, ptr @n, align 4, !tbaa !4
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.15, i32 noundef signext %14)
+ %15 = load i32, ptr @o, align 4, !tbaa !4
+ %call16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.16, i32 noundef signext %15)
+ %16 = load i32, ptr @p, align 4, !tbaa !4
+ %call17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.17, i32 noundef signext %16)
+ %17 = load i32, ptr @q, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.18, i32 noundef signext %17)
+ %18 = load i32, ptr @r, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.19, i32 noundef signext %18)
+ %19 = load i32, ptr @s, align 4, !tbaa !4
+ %call20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.20, i32 noundef signext %19)
+ %20 = load i32, ptr @t, align 4, !tbaa !4
+ %call21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.21, i32 noundef signext %20)
br label %if.end
if.end: ; preds = %if.else, %if.then
- %23 = load i32, ptr @a, align 4, !tbaa !4
- %24 = load i32, ptr @b, align 4, !tbaa !4
- %add = add nsw i32 %24, %23
- %25 = load i32, ptr @c, align 4, !tbaa !4
- %add22 = add nsw i32 %add, %25
- %26 = load i32, ptr @d, align 4, !tbaa !4
- %add23 = add nsw i32 %add22, %26
- %27 = load i32, ptr @e, align 4, !tbaa !4
- %add24 = add nsw i32 %add23, %27
- %28 = load i32, ptr @f, align 4, !tbaa !4
- %add25 = add nsw i32 %add24, %28
- %29 = load i32, ptr @g, align 4, !tbaa !4
- %add26 = add nsw i32 %add25, %29
- %30 = load i32, ptr @h, align 4, !tbaa !4
- %add27 = add nsw i32 %add26, %30
- %31 = load i32, ptr @i, align 4, !tbaa !4
- %add28 = add nsw i32 %add27, %31
- %32 = load i32, ptr @j, align 4, !tbaa !4
- %add29 = add nsw i32 %add28, %32
- %33 = load i32, ptr @k, align 4, !tbaa !4
- %add30 = add nsw i32 %add29, %33
- %34 = load i32, ptr @l, align 4, !tbaa !4
- %add31 = add nsw i32 %add30, %34
- %35 = load i32, ptr @m, align 4, !tbaa !4
- %add32 = add nsw i32 %add31, %35
- %36 = load i32, ptr @n, align 4, !tbaa !4
- %add33 = add nsw i32 %add32, %36
- %37 = load i32, ptr @o, align 4, !tbaa !4
- %add34 = add nsw i32 %add33, %37
- %38 = load i32, ptr @p, align 4, !tbaa !4
- %add35 = add nsw i32 %add34, %38
- %39 = load i32, ptr @q, align 4, !tbaa !4
- %add36 = add nsw i32 %add35, %39
- %40 = load i32, ptr @r, align 4, !tbaa !4
- %add37 = add nsw i32 %add36, %40
- %41 = load i32, ptr @s, align 4, !tbaa !4
- %add38 = add nsw i32 %add37, %41
- %42 = load i32, ptr @t, align 4, !tbaa !4
- %add39 = add nsw i32 %add38, %42
+ %21 = load i32, ptr @a, align 4, !tbaa !4
+ %22 = load i32, ptr @b, align 4, !tbaa !4
+ %add = add nsw i32 %22, %21
+ %23 = load i32, ptr @c, align 4, !tbaa !4
+ %add22 = add nsw i32 %add, %23
+ %24 = load i32, ptr @d, align 4, !tbaa !4
+ %add23 = add nsw i32 %add22, %24
+ %25 = load i32, ptr @e, align 4, !tbaa !4
+ %add24 = add nsw i32 %add23, %25
+ %26 = load i32, ptr @f, align 4, !tbaa !4
+ %add25 = add nsw i32 %add24, %26
+ %27 = load i32, ptr @g, align 4, !tbaa !4
+ %add26 = add nsw i32 %add25, %27
+ %28 = load i32, ptr @h, align 4, !tbaa !4
+ %add27 = add nsw i32 %add26, %28
+ %29 = load i32, ptr @i, align 4, !tbaa !4
+ %add28 = add nsw i32 %add27, %29
+ %30 = load i32, ptr @j, align 4, !tbaa !4
+ %add29 = add nsw i32 %add28, %30
+ %31 = load i32, ptr @k, align 4, !tbaa !4
+ %add30 = add nsw i32 %add29, %31
+ %32 = load i32, ptr @l, align 4, !tbaa !4
+ %add31 = add nsw i32 %add30, %32
+ %33 = load i32, ptr @m, align 4, !tbaa !4
+ %add32 = add nsw i32 %add31, %33
+ %34 = load i32, ptr @n, align 4, !tbaa !4
+ %add33 = add nsw i32 %add32, %34
+ %35 = load i32, ptr @o, align 4, !tbaa !4
+ %add34 = add nsw i32 %add33, %35
+ %36 = load i32, ptr @p, align 4, !tbaa !4
+ %add35 = add nsw i32 %add34, %36
+ %37 = load i32, ptr @q, align 4, !tbaa !4
+ %add36 = add nsw i32 %add35, %37
+ %38 = load i32, ptr @r, align 4, !tbaa !4
+ %add37 = add nsw i32 %add36, %38
+ %39 = load i32, ptr @s, align 4, !tbaa !4
+ %add38 = add nsw i32 %add37, %39
+ %40 = load i32, ptr @t, align 4, !tbaa !4
+ %add39 = add nsw i32 %add38, %40
ret i32 %add39
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none)
-declare ptr @llvm.frameaddress.p0(i32 immarg) #1
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn
-declare ptr @llvm.stacksave.p0() #2
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #1
; Function Attrs: nofree nounwind
-declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #4
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #2
-declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #5
+declare void @foo(ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #3
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #4
attributes #0 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) }
-attributes #2 = { mustprogress nocallback nofree nosync nounwind willreturn }
-attributes #3 = { nounwind }
-attributes #4 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #5 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #6 = { nofree nounwind }
+attributes #1 = { nounwind }
+attributes #2 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
>From 4fa29144dd8c2b2e20ec85f1a7fb4e5a9167cec0 Mon Sep 17 00:00:00 2001
From: anoop-kumar6 <anoop.kumar6 at ibm.com>
Date: Fri, 25 Oct 2024 16:57:00 +0200
Subject: [PATCH 4/9] Not to check FP live in setjmp.
---
llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 983215bf28519e..1969709a00272b 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -1045,7 +1045,7 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
.addReg(0);
bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
- if (HasFP || MBB->isLiveIn(SystemZ::R11D)) {
+ if (HasFP) {
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
.addReg(SystemZ::R11D)
.addReg(BufReg)
>From b289df99d26b008287e18cdb0858bc569de3f2ad Mon Sep 17 00:00:00 2001
From: anoop-kumar6 <anoop.kumar6 at ibm.com>
Date: Fri, 25 Oct 2024 17:25:25 +0200
Subject: [PATCH 5/9] Remove store of R13.
---
llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 47668e6ea58c8d..9dee4263d6a8d6 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -1080,18 +1080,6 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
.addReg(0);
}
- // LP Literal Pool register in fifth slot.
- if (MBB->isLiveIn(SystemZ::R13D)) {
- // If R13 is not live, and It is non-reserved physical register, we get
- // assertion - Using an undefined physical register.
- const int64_t LPOffset = 4 * PVT.getStoreSize(); // Slot 5.
- BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
- .addReg(SystemZ::R13D)
- .addReg(BufReg)
- .addImm(LPOffset)
- .addReg(0);
- }
-
// Setup.
MIB = BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::EH_SjLj_Setup))
.addMBB(restoreMBB);
>From a0433728375e658551506ce43b0848200fdd6e61 Mon Sep 17 00:00:00 2001
From: anoop-kumar6 <anoop.kumar6 at ibm.com>
Date: Wed, 30 Oct 2024 02:28:49 +0100
Subject: [PATCH 6/9] Incorporate code review changes and added new test cases.
---
.../Target/SystemZ/SystemZISelLowering.cpp | 51 +-
llvm/lib/Target/SystemZ/SystemZISelLowering.h | 4 -
.../CodeGen/SystemZ/builtin-longjmp-01.ll | 2 +-
.../SystemZ/builtin-longjmp-backchain-01.ll | 4 +-
.../SystemZ/builtin-setjmp-longjmp-02.ll | 6 +-
.../builtin-setjmp-longjmp-alloca-00.ll | 6 +-
.../builtin-setjmp-longjmp-alloca-01.ll | 319 +++-
.../builtin-setjmp-longjmp-alloca-02.ll | 369 ++--
.../builtin-setjmp-longjmp-alloca-03.ll | 1660 ++++++++--------
...ltin-setjmp-longjmp-alloca-backchain-01.ll | 343 ++++
...ltin-setjmp-longjmp-alloca-backchain-02.ll | 396 ++--
...ltin-setjmp-longjmp-alloca-backchain-03.ll | 1667 +++++++++--------
.../builtin-setjmp-longjmp-literal-pool-00.ll | 5 +-
.../builtin-setjmp-longjmp-literal-pool-01.ll | 15 +-
.../builtin-setjmp-longjmp-literal-pool-02.ll | 14 +-
.../builtin-setjmp-longjmp-literal-pool-03.ll | 425 ++---
.../builtin-setjmp-longjmp-literal-pool-04.ll | 264 +++
...etjmp-longjmp-literal-pool-backchain-00.ll | 8 +-
...etjmp-longjmp-literal-pool-backchain-01.ll | 175 ++
...etjmp-longjmp-literal-pool-backchain-02.ll | 277 +++
...etjmp-longjmp-literal-pool-backchain-03.ll | 290 +++
...etjmp-longjmp-literal-pool-backchain-04.ll | 264 +++
.../builtin-setjmp-spills-double-01.ll | 2 +-
.../builtin-setjmp-spills-double-02.ll | 2 +-
.../builtin-setjmp-spills-double-03.ll | 2 +-
...iltin-setjmp-spills-double-backchain-01.ll | 2 +-
...iltin-setjmp-spills-double-backchain-02.ll | 2 +-
...iltin-setjmp-spills-double-backchain-03.ll | 2 +-
.../SystemZ/builtin-setjmp-spills-int-01.ll | 2 +-
.../SystemZ/builtin-setjmp-spills-int-02.ll | 2 +-
.../SystemZ/builtin-setjmp-spills-int-03.ll | 2 +-
.../builtin-setjmp-spills-int-backchain-01.ll | 2 +-
.../builtin-setjmp-spills-int-backchain-02.ll | 2 +-
.../builtin-setjmp-spills-int-backchain-03.ll | 2 +-
34 files changed, 4112 insertions(+), 2476 deletions(-)
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-04.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-01.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-02.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-04.ll
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 9dee4263d6a8d6..f498f9eab865f1 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -747,10 +747,11 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
ISD::INTRINSIC_VOID,
ISD::INTRINSIC_W_CHAIN});
+ // Handle intrinsics.
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
- // we're not using SJLJ for exception handling, but they're implemented
+ // We're not using SJLJ for exception handling, but they're implemented
// solely to support use of __builtin_setjmp / __builtin_longjmp.
setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
@@ -995,15 +996,12 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
// buf[LabelOffset] = restoreMBB <-- takes address of restoreMBB.
// buf[BCOffset] = Backchain value if building with -mbackchain.
// buf[SPOffset] = Stack Pointer.
- // buf[LPOffset] = Literal Pool Pointer if R13 live.
+ // buf[LPOffset] = We never write this slot with R13, gcc stores R13 always.
// SjLjSetup restoreMBB
- //
// mainMBB:
// v_main = 0
- //
// sinkMBB:
// v = phi(v_main, v_restore)
- //
// restoreMBB:
// v_restore = 1
@@ -1049,10 +1047,11 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
if (HasFP) {
+ const int64_t FPOffset = 0;
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
.addReg(SystemZ::R11D)
.addReg(BufReg)
- .addImm(0)
+ .addImm(FPOffset)
.addReg(0);
}
@@ -1128,9 +1127,11 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
const TargetRegisterClass *RC = MRI.getRegClass(BufReg);
Register Tmp = MRI.createVirtualRegister(RC);
+ Register BCReg = MRI.createVirtualRegister(RC);
MachineInstrBuilder MIB;
+ const int64_t FPOffset = 0;
const int64_t LabelOffset = 1 * PVT.getStoreSize();
const int64_t SPOffset = 3 * PVT.getStoreSize();
const int64_t LPOffset = 4 * PVT.getStoreSize();
@@ -1142,9 +1143,12 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R11D)
.addReg(BufReg)
- .addImm(0)
+ .addImm(FPOffset)
.addReg(0);
+ // We are restoring R13 even though we never stored in setjmp from llvm,
+ // as gcc always stores R13 in builtin_setjmp. We could have mixed code
+ // gcc setjmp and llvm longjmp.
MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R13D)
.addReg(BufReg)
.addImm(LPOffset)
@@ -1153,12 +1157,18 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain();
if (BackChain) {
const int64_t BCOffset = 2 * PVT.getStoreSize();
- Register BCReg = MRI.createVirtualRegister(RC);
MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), BCReg)
.addReg(BufReg)
.addImm(BCOffset)
.addReg(0);
+ }
+
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R15D)
+ .addReg(BufReg)
+ .addImm(SPOffset)
+ .addReg(0);
+ if (BackChain) {
BuildMI(*MBB, MI, DL, TII->get(SystemZ::STG))
.addReg(BCReg)
.addReg(SystemZ::R15D)
@@ -1166,18 +1176,13 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
.addReg(0);
}
- MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R15D)
- .addReg(BufReg)
- .addImm(SPOffset)
- .addReg(0);
-
MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::BR)).addReg(Tmp);
MI.eraseFromParent();
return MBB;
}
-/// Returns true if stack probing through inline assembly is requested.
+// Returns true if stack probing through inline assembly is requested.
bool SystemZTargetLowering::hasInlineStackProbe(const MachineFunction &MF) const {
// If the function specifically requests inline stack probes, emit them.
if (MF.getFunction().hasFnAttribute("probe-stack"))
@@ -6530,9 +6535,8 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
case ISD::READCYCLECOUNTER:
return lowerREADCYCLECOUNTER(Op, DAG);
case ISD::EH_SJLJ_SETJMP:
- return lowerEH_SJLJ_SETJMP(Op, DAG);
case ISD::EH_SJLJ_LONGJMP:
- return lowerEH_SJLJ_LONGJMP(Op, DAG);
+ return Op;
default:
llvm_unreachable("Unexpected node to lower");
@@ -10030,21 +10034,6 @@ SDValue SystemZTargetLowering::lowerGET_ROUNDING(SDValue Op,
return DAG.getMergeValues({RetVal, Chain}, dl);
}
-SDValue SystemZTargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
- SelectionDAG &DAG) const {
- SDLoc DL(Op);
- return DAG.getNode(ISD::EH_SJLJ_SETJMP, DL,
- DAG.getVTList(MVT::i32, MVT::Other),
- Op.getOperand(0), Op.getOperand(1));
-}
-
-SDValue SystemZTargetLowering::lowerEH_SJLJ_LONGJMP(SDValue Op,
- SelectionDAG &DAG) const {
- SDLoc DL(Op);
- return DAG.getNode(ISD::EH_SJLJ_LONGJMP, DL, MVT::Other,
- Op.getOperand(0), Op.getOperand(1));
-}
-
SDValue SystemZTargetLowering::lowerVECREDUCE_ADD(SDValue Op,
SelectionDAG &DAG) const {
EVT VT = Op.getValueType();
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index 9f6594c5aec71c..92ac938c903b68 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -305,8 +305,6 @@ enum NodeType : unsigned {
// function descriptor)
ADA_ENTRY,
-
-
// Strict variants of scalar floating-point comparisons.
// Quiet and signaling versions.
STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
@@ -730,8 +728,6 @@ class SystemZTargetLowering : public TargetLowering {
SDValue lowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
- SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
- SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
bool canTreatAsByteVector(EVT VT) const;
diff --git a/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll b/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll
index fb6f19bbb9e05a..413b651acb64a7 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-longjmp-01.ll
@@ -4,7 +4,7 @@
; Stack Pointer from Slot 4.
; Literal Pool Pointer from Slot 5.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'longjmp.c'
diff --git a/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
index dde5b7ea498dbc..39ee483c27cbd5 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
@@ -5,7 +5,7 @@
; Stack Pointer from Slot 4.
; Literal Pool Pointer from Slot 5.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'longjmp.c'
source_filename = "longjmp.c"
@@ -23,8 +23,8 @@ entry:
; CHECK: lg %r11, 0(%r1)
; CHECK: lg %r13, 32(%r1)
; CHECK: lg %r3, 16(%r1)
-; CHECK: stg %r3, 0(%r15)
; CHECK: lg %r15, 24(%r1)
+; CHECK: stg %r3, 0(%r15)
; CHECK: br %r2
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll
index 07307e91d07b04..31026afcc5689b 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-02.ll
@@ -4,7 +4,7 @@
; Stack Pointer from Slot 4.
; Literal Pool Pointer from Slot 5.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O1 < %s | FileCheck %s
; CHECK: stmg %r11, %r15, 88(%r15)
; CHECK: aghi %r15, -160
; CHECK: lgrl %r2, .Lstr at GOT
@@ -60,6 +60,10 @@ if.then: ; preds = %entry
unreachable
if.end: ; preds = %entry
+;Test longjmp store to jmp_buf.
+; Frame pointer from Slot 1.
+; Jump address from Slot 2.
+; Stack Pointer from Slot 4.
; CHECK: larl %r1, buf
; CHECK: larl %r0, .LBB2_3
; CHECK: stg %r0, 8(%r1)
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll
index ec8483344109d4..37f24e7975a6e5 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll
@@ -1,5 +1,7 @@
; This tests Frame Pointer.
-; This test case produces Wrong result.
+; This test case produces Wrong result when len of malloc is local int variable.
+; But its output is correct when len is global int len, local volatile int len.
+
; FIXME: Correct Output is:
;First __builtin_setjmp in func1
;Second __builtin_setjmp in func1
@@ -28,7 +30,7 @@
; TODO: test case with -mbackchain
-; RUN: clang -o %t %s
+; RUN: clang -O2 -o %t %s
; RUN: %t | FileCheck %s
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll
index c3105c0085470a..812ca45e259681 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-01.ll
@@ -1,13 +1,9 @@
-; llvm-lit does not take input from stdin, test case produces right result.
-; This test case produces right result when alloca size is unknown.
+; This test case produces right result when alloca size is not local variable.
; Test output of setjmp/longjmp with nested setjmp for alloca
; Test for Frame Pointer in first slot in jmp_buf.
-; FIXME: Take input from stdin for size of alloca.
-; TODO: -mbackchain
-
-; RUN: clang -o %t %s
-; RUN: %t | FileCheck %s
+; RUN: clang -O2 -o %t %s
+; RUN: %t 10 | FileCheck %s
; ModuleID = 'builtin-setjmp-longjmp-alloca-01.c'
source_filename = "builtin-setjmp-longjmp-alloca-01.c"
@@ -19,14 +15,15 @@ target triple = "s390x-unknown-linux-gnu"
@buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
@.str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
@str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
- at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
- at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
- at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
- at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
- at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
- at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
- at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
- at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.13 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.14 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.15 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.16 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.17 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.18 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.19 = private unnamed_addr constant [30 x i8] c"Usage: program_name <length> \00", align 1
; Function Attrs: noinline noreturn nounwind
define dso_local void @func4() local_unnamed_addr #0 {
@@ -45,7 +42,7 @@ declare void @llvm.eh.sjlj.longjmp(ptr) #2
; Function Attrs: noinline noreturn nounwind
define dso_local void @func3() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
unreachable
}
@@ -53,26 +50,92 @@ entry:
; Function Attrs: noinline noreturn nounwind
define dso_local void @func2() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
unreachable
}
; Function Attrs: noreturn nounwind
-define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+define dso_local noundef signext i32 @func1(i32 noundef signext %len) local_unnamed_addr #3 {
entry:
- %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
- %cmp3 = icmp eq i32 %0, 0
+ %conv = sext i32 %len to i64
+ %mul = shl nsw i64 %conv, 2
+ %0 = alloca i8, i64 %mul, align 8
+ %cmp84 = icmp sgt i32 %len, 0
+ br i1 %cmp84, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %wide.trip.count = zext nneg i32 %len to i64
+ %xtraiter = and i64 %wide.trip.count, 3
+ %1 = icmp ult i32 %len, 4
+ br i1 %1, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
+
+for.body.preheader.new: ; preds = %for.body.preheader
+ %unroll_iter = and i64 %wide.trip.count, 2147483644
+ br label %for.body
+
+for.cond.cleanup.loopexit.unr-lcssa: ; preds = %for.body, %for.body.preheader
+ %indvars.iv.unr = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next.3, %for.body ]
+ %lcmp.mod.not = icmp eq i64 %xtraiter, 0
+ br i1 %lcmp.mod.not, label %for.cond.cleanup, label %for.body.epil
+
+for.body.epil: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil
+ %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %for.body.epil ], [ %indvars.iv.unr, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
+ %indvars.epil = trunc i64 %indvars.iv.next.epil to i32
+ %2 = trunc nuw nsw i64 %indvars.iv.epil to i32
+ %add.epil = mul i32 %indvars.epil, %2
+ %arrayidx.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.epil
+ store i32 %add.epil, ptr %arrayidx.epil, align 4, !tbaa !4
+ %epil.iter.next = add i64 %epil.iter, 1
+ %epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
+ br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
+
+for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
+ %3 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %3, 0
br i1 %cmp3, label %if.then, label %if.else38
-if.then: ; preds = %entry
- %puts77 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
- %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
- %cmp5 = icmp eq i32 %1, 0
+for.body: ; preds = %for.body, %for.body.preheader.new
+ %indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
+ %niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
+ %indvars.iv.next = or disjoint i64 %indvars.iv, 1
+ %indvars = trunc i64 %indvars.iv.next to i32
+ %4 = trunc nuw nsw i64 %indvars.iv to i32
+ %add = mul i32 %indvars, %4
+ %arrayidx = getelementptr inbounds i32, ptr %0, i64 %indvars.iv
+ store i32 %add, ptr %arrayidx, align 8, !tbaa !4
+ %indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
+ %indvars.1 = trunc i64 %indvars.iv.next.1 to i32
+ %5 = trunc nuw nsw i64 %indvars.iv.next to i32
+ %add.1 = mul i32 %indvars.1, %5
+ %arrayidx.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next
+ store i32 %add.1, ptr %arrayidx.1, align 4, !tbaa !4
+ %indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
+ %indvars.2 = trunc i64 %indvars.iv.next.2 to i32
+ %6 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
+ %add.2 = mul i32 %indvars.2, %6
+ %arrayidx.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.1
+ store i32 %add.2, ptr %arrayidx.2, align 8, !tbaa !4
+ %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
+ %indvars.3 = trunc i64 %indvars.iv.next.3 to i32
+ %7 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
+ %add.3 = mul i32 %indvars.3, %7
+ %arrayidx.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.2
+ store i32 %add.3, ptr %arrayidx.3, align 4, !tbaa !4
+ %niter.next.3 = add i64 %niter, 4
+ %niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
+ br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
+
+if.then: ; preds = %for.cond.cleanup
+ %puts77 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %8 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %8, 0
br i1 %cmp5, label %if.then7, label %if.else
if.then7: ; preds = %if.then
- %puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
; CHECK: First __builtin_setjmp in func1
; CHECK: Second __builtin_setjmp in func1
; CHECK: Returned from func4
@@ -88,48 +151,6 @@ if.then7: ; preds = %if.then
; CHECK: arr: 90
; CHECK: Returned from func3
; CHECK: arr: 0
-; CHECK: arr: 3
-; CHECK: arr: 14
-; CHECK: arr: 39
-; CHECK: arr: 84
-; CHECK: arr: 155
-; CHECK: arr: 258
-; CHECK: arr: 399
-; CHECK: arr: 584
-; CHECK: arr: 819
-
- tail call void @func4()
- unreachable
-
-if.else: ; preds = %if.then
- %puts78 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
- %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
- %call18.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
- %call18.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
- %call18.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
- %call18.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
- %call18.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
- %call18.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
- %call18.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
- %call18.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
- %call18.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
- tail call void @func3()
- unreachable
-
-if.else38: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
- %call48 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
- %call48.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
- %call48.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
- %call48.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
- %call48.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
- %call48.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
- %call48.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
- %call48.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
- %call48.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
- %call48.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
-; CHECK: Returned from func3
-; CHECK: arr: 0
; CHECK: arr: 3
; CHECK: arr: 14
; CHECK: arr: 39
@@ -140,32 +161,155 @@ if.else38: ; preds = %entry
; CHECK: arr: 584
; CHECK: arr: 819
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts78 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ br i1 %cmp84, label %for.body15.preheader, label %for.cond.cleanup26
+
+for.body15.preheader: ; preds = %if.else
+ %wide.trip.count103 = zext nneg i32 %len to i64
+ br label %for.body15
+
+for.body27.preheader: ; preds = %for.body15
+ %xtraiter111 = and i64 %wide.trip.count103, 3
+ %9 = icmp ult i32 %len, 4
+ br i1 %9, label %for.cond.cleanup26.loopexit.unr-lcssa, label %for.body27.preheader.new
+
+for.body27.preheader.new: ; preds = %for.body27.preheader
+ %unroll_iter114 = and i64 %wide.trip.count103, 2147483644
+ br label %for.body27
+
+for.body15: ; preds = %for.body15.preheader, %for.body15
+ %indvars.iv99 = phi i64 [ 0, %for.body15.preheader ], [ %indvars.iv.next100, %for.body15 ]
+ %arrayidx17 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv99
+ %10 = load i32, ptr %arrayidx17, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %10)
+ %indvars.iv.next100 = add nuw nsw i64 %indvars.iv99, 1
+ %exitcond104.not = icmp eq i64 %indvars.iv.next100, %wide.trip.count103
+ br i1 %exitcond104.not, label %for.body27.preheader, label %for.body15, !llvm.loop !12
+
+for.cond.cleanup26.loopexit.unr-lcssa: ; preds = %for.body27, %for.body27.preheader
+ %indvars.iv105.unr = phi i64 [ 0, %for.body27.preheader ], [ %indvars.iv.next106.3, %for.body27 ]
+ %lcmp.mod113.not = icmp eq i64 %xtraiter111, 0
+ br i1 %lcmp.mod113.not, label %for.cond.cleanup26, label %for.body27.epil
+
+for.body27.epil: ; preds = %for.cond.cleanup26.loopexit.unr-lcssa, %for.body27.epil
+ %indvars.iv105.epil = phi i64 [ %indvars.iv.next106.epil, %for.body27.epil ], [ %indvars.iv105.unr, %for.cond.cleanup26.loopexit.unr-lcssa ]
+ %epil.iter112 = phi i64 [ %epil.iter112.next, %for.body27.epil ], [ 0, %for.cond.cleanup26.loopexit.unr-lcssa ]
+ %indvars.iv.next106.epil = add nuw nsw i64 %indvars.iv105.epil, 1
+ %indvars107.epil = trunc i64 %indvars.iv.next106.epil to i32
+ %11 = trunc nuw nsw i64 %indvars.iv105.epil to i32
+ %mul2979.epil = mul i32 %indvars107.epil, %11
+ %add3181.epil = add nuw nsw i32 %mul2979.epil, 1
+ %add32.epil = mul i32 %add3181.epil, %11
+ %arrayidx34.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv105.epil
+ store i32 %add32.epil, ptr %arrayidx34.epil, align 4, !tbaa !4
+ %epil.iter112.next = add i64 %epil.iter112, 1
+ %epil.iter112.cmp.not = icmp eq i64 %epil.iter112.next, %xtraiter111
+ br i1 %epil.iter112.cmp.not, label %for.cond.cleanup26, label %for.body27.epil, !llvm.loop !13
+
+for.cond.cleanup26: ; preds = %for.cond.cleanup26.loopexit.unr-lcssa, %for.body27.epil, %if.else
+ tail call void @func3()
+ unreachable
+
+for.body27: ; preds = %for.body27, %for.body27.preheader.new
+ %indvars.iv105 = phi i64 [ 0, %for.body27.preheader.new ], [ %indvars.iv.next106.3, %for.body27 ]
+ %niter115 = phi i64 [ 0, %for.body27.preheader.new ], [ %niter115.next.3, %for.body27 ]
+ %indvars.iv.next106 = or disjoint i64 %indvars.iv105, 1
+ %indvars107 = trunc i64 %indvars.iv.next106 to i32
+ %12 = trunc nuw nsw i64 %indvars.iv105 to i32
+ %mul2979 = mul i32 %indvars107, %12
+ %add3181 = or disjoint i32 %mul2979, 1
+ %add32 = mul i32 %add3181, %12
+ %arrayidx34 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv105
+ store i32 %add32, ptr %arrayidx34, align 8, !tbaa !4
+ %indvars.iv.next106.1 = or disjoint i64 %indvars.iv105, 2
+ %indvars107.1 = trunc i64 %indvars.iv.next106.1 to i32
+ %13 = trunc nuw nsw i64 %indvars.iv.next106 to i32
+ %mul2979.1 = mul i32 %indvars107.1, %13
+ %add3181.1 = or disjoint i32 %mul2979.1, 1
+ %add32.1 = mul i32 %add3181.1, %13
+ %arrayidx34.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106
+ store i32 %add32.1, ptr %arrayidx34.1, align 4, !tbaa !4
+ %indvars.iv.next106.2 = or disjoint i64 %indvars.iv105, 3
+ %indvars107.2 = trunc i64 %indvars.iv.next106.2 to i32
+ %14 = trunc nuw nsw i64 %indvars.iv.next106.1 to i32
+ %mul2979.2 = mul i32 %indvars107.2, %14
+ %add3181.2 = or disjoint i32 %mul2979.2, 1
+ %add32.2 = mul i32 %add3181.2, %14
+ %arrayidx34.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106.1
+ store i32 %add32.2, ptr %arrayidx34.2, align 8, !tbaa !4
+ %indvars.iv.next106.3 = add nuw nsw i64 %indvars.iv105, 4
+ %indvars107.3 = trunc i64 %indvars.iv.next106.3 to i32
+ %15 = trunc nuw nsw i64 %indvars.iv.next106.2 to i32
+ %mul2979.3 = mul i32 %indvars107.3, %15
+ %add3181.3 = or disjoint i32 %mul2979.3, 1
+ %add32.3 = mul i32 %add3181.3, %15
+ %arrayidx34.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106.2
+ store i32 %add32.3, ptr %arrayidx34.3, align 4, !tbaa !4
+ %niter115.next.3 = add i64 %niter115, 4
+ %niter115.ncmp.3 = icmp eq i64 %niter115.next.3, %unroll_iter114
+ br i1 %niter115.ncmp.3, label %for.cond.cleanup26.loopexit.unr-lcssa, label %for.body27, !llvm.loop !14
+
+if.else38: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ br i1 %cmp84, label %for.body45.preheader, label %for.cond.cleanup44
+
+for.body45.preheader: ; preds = %if.else38
+ %wide.trip.count97 = zext nneg i32 %len to i64
+ br label %for.body45
+
+for.cond.cleanup44: ; preds = %for.body45, %if.else38
tail call void @func2()
unreachable
+
+for.body45: ; preds = %for.body45.preheader, %for.body45
+ %indvars.iv93 = phi i64 [ 0, %for.body45.preheader ], [ %indvars.iv.next94, %for.body45 ]
+ %arrayidx47 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv93
+ %16 = load i32, ptr %arrayidx47, align 4, !tbaa !4
+ %call48 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %16)
+ %indvars.iv.next94 = add nuw nsw i64 %indvars.iv93, 1
+ %exitcond98.not = icmp eq i64 %indvars.iv.next94, %wide.trip.count97
+ br i1 %exitcond98.not, label %for.cond.cleanup44, label %for.body45, !llvm.loop !15
}
; Function Attrs: nounwind
declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
; Function Attrs: nounwind
-define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+define dso_local signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readonly %argv) local_unnamed_addr #5 {
entry:
- %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
- %cmp = icmp eq i32 %0, 0
- br i1 %cmp, label %if.then, label %if.else
+ %cmp = icmp slt i32 %argc, 2
+ br i1 %cmp, label %return, label %if.end
-if.then: ; preds = %entry
- %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
- %call1 = tail call signext i32 @func1()
+if.end: ; preds = %entry
+ %arrayidx = getelementptr inbounds i8, ptr %argv, i64 8
+ %0 = load ptr, ptr %arrayidx, align 8, !tbaa !16
+ %call.i = tail call i64 @strtol(ptr nocapture noundef nonnull %0, ptr noundef null, i32 noundef signext 10) #4
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp2 = icmp eq i32 %1, 0
+ br i1 %cmp2, label %if.then3, label %return
+
+if.then3: ; preds = %if.end
+ %conv.i = trunc i64 %call.i to i32
+ %puts8 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %call5 = tail call signext i32 @func1(i32 noundef signext %conv.i)
unreachable
-if.else: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
- ret i32 0
+return: ; preds = %if.end, %entry
+ %str.17.sink = phi ptr [ @str.19, %entry ], [ @str.17, %if.end ]
+ %retval.0 = phi i32 [ 1, %entry ], [ 0, %if.end ]
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) %str.17.sink)
+ ret i32 %retval.0
}
+; Function Attrs: mustprogress nofree nounwind willreturn
+declare i64 @strtol(ptr noundef readonly, ptr nocapture noundef, i32 noundef signext) local_unnamed_addr #6
+
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
@@ -173,7 +317,8 @@ attributes #2 = { noreturn nounwind }
attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #4 = { nounwind }
attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #6 = { nofree nounwind }
+attributes #6 = { mustprogress nofree nounwind willreturn "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -181,4 +326,18 @@ attributes #6 = { nofree nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = distinct !{!8, !9}
+!9 = !{!"llvm.loop.unroll.disable"}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
+!13 = distinct !{!13, !9}
+!14 = distinct !{!14, !11}
+!15 = distinct !{!15, !11}
+!16 = !{!17, !17, i64 0}
+!17 = !{!"any pointer", !6, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll
index 1a24e0f0ee12d1..6ede0bf5b25082 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-02.ll
@@ -1,34 +1,35 @@
; Test for Frame Pointer in first slot in jmp_buf.
-; Test assembly for nested setjmp for alloa.
-; This test case takes input from stdin for size of alloca
-; and produce the right result.
+; Test assembly for store/load to/from for nested setjmp for alloca for
+; setjmp/longjmp respectively.
+
+; Test for Frame Pointer in first slot in jmp_buf.
+; Test assembly for nested setjmp for alloca.
; Frame Pointer in slot 1.
; Return address in slot 2.
; Stack Pointer in slot 4.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
-; ModuleID = 'builtin-setjmp-longjmp-alloca-01.c'
-source_filename = "builtin-setjmp-longjmp-alloca-01.c"
+; ModuleID = 'builtin-setjmp-longjmp-alloca-02.c'
+source_filename = "builtin-setjmp-longjmp-alloca-02.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
target triple = "s390x-unknown-linux-gnu"
@buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
- at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
- at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
- at .str.8 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at len = dso_local local_unnamed_addr global i32 10, align 4
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
@str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
- at str.12 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
- at str.13 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
- at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
- at str.15 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
- at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
- at str.17 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
- at str.18 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
- at str.19 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
; Function Attrs: noinline noreturn nounwind
define dso_local void @func4() local_unnamed_addr #0 {
@@ -47,7 +48,18 @@ declare void @llvm.eh.sjlj.longjmp(ptr) #2
; Function Attrs: noinline noreturn nounwind
define dso_local void @func3() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+; Load Frame Pointer from slot 1.
+; Load return address from slot 2.
+; Load stack pointer from slot 4.
+; Load literal pointer from slot 5.
+
+; CHECK: larl %r1, buf2
+; CHECK: lg %r2, 8(%r1)
+; CHECK: lg %r11, 0(%r1)
+; CHECK: lg %r13, 32(%r1)
+; CHECK: lg %r15, 24(%r1)
+; CHECK: br %r2
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
unreachable
}
@@ -55,31 +67,25 @@ entry:
; Function Attrs: noinline noreturn nounwind
define dso_local void @func2() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
unreachable
}
; Function Attrs: noreturn nounwind
-define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+define dso_local noundef signext i32 @func1(i32 noundef signext %len) local_unnamed_addr #3 {
entry:
- %len = alloca i32, align 4
- call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
- store i32 10, ptr %len, align 4, !tbaa !4
- %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
- %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
- %0 = load i32, ptr %len, align 4, !tbaa !4
- %conv = sext i32 %0 to i64
+ %conv = sext i32 %len to i64
%mul = shl nsw i64 %conv, 2
- %1 = alloca i8, i64 %mul, align 8
- %cmp82 = icmp sgt i32 %0, 0
- br i1 %cmp82, label %for.body.preheader, label %for.cond.cleanup
+ %0 = alloca i8, i64 %mul, align 8
+ %cmp84 = icmp sgt i32 %len, 0
+ br i1 %cmp84, label %for.body.preheader, label %for.cond.cleanup
for.body.preheader: ; preds = %entry
- %wide.trip.count = zext nneg i32 %0 to i64
+ %wide.trip.count = zext nneg i32 %len to i64
%xtraiter = and i64 %wide.trip.count, 3
- %2 = icmp ult i32 %0, 4
- br i1 %2, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
+ %1 = icmp ult i32 %len, 4
+ br i1 %1, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
for.body.preheader.new: ; preds = %for.body.preheader
%unroll_iter = and i64 %wide.trip.count, 2147483644
@@ -95,219 +101,212 @@ for.body.epil: ; preds = %for.cond.cleanup.lo
%epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
%indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
%indvars.epil = trunc i64 %indvars.iv.next.epil to i32
- %3 = trunc nuw nsw i64 %indvars.iv.epil to i32
- %add.epil = mul i32 %indvars.epil, %3
- %arrayidx.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.epil
+ %2 = trunc nuw nsw i64 %indvars.iv.epil to i32
+ %add.epil = mul i32 %indvars.epil, %2
+ %arrayidx.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.epil
store i32 %add.epil, ptr %arrayidx.epil, align 4, !tbaa !4
%epil.iter.next = add i64 %epil.iter, 1
%epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
+; Store Frame Pointer in slot 1.
+; Store Return address in slot 2.
+; Store Stack Pointer in slot 4
+
; CHECK: larl %r0, .LBB3_13
; CHECK: stg %r0, 8(%r1)
; CHECK: stg %r11, 0(%r1)
; CHECK: stg %r15, 24(%r1)
- %4 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
- %cmp4 = icmp eq i32 %4, 0
- br i1 %cmp4, label %if.then, label %if.else40
+ %3 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %3, 0
+ br i1 %cmp3, label %if.then, label %if.else38
for.body: ; preds = %for.body, %for.body.preheader.new
%indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
%niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
%indvars.iv.next = or disjoint i64 %indvars.iv, 1
%indvars = trunc i64 %indvars.iv.next to i32
- %5 = trunc nuw nsw i64 %indvars.iv to i32
- %add = mul i32 %indvars, %5
- %arrayidx = getelementptr inbounds i32, ptr %1, i64 %indvars.iv
+ %4 = trunc nuw nsw i64 %indvars.iv to i32
+ %add = mul i32 %indvars, %4
+ %arrayidx = getelementptr inbounds i32, ptr %0, i64 %indvars.iv
store i32 %add, ptr %arrayidx, align 8, !tbaa !4
%indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
%indvars.1 = trunc i64 %indvars.iv.next.1 to i32
- %6 = trunc nuw nsw i64 %indvars.iv.next to i32
- %add.1 = mul i32 %indvars.1, %6
- %arrayidx.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next
+ %5 = trunc nuw nsw i64 %indvars.iv.next to i32
+ %add.1 = mul i32 %indvars.1, %5
+ %arrayidx.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next
store i32 %add.1, ptr %arrayidx.1, align 4, !tbaa !4
%indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
%indvars.2 = trunc i64 %indvars.iv.next.2 to i32
- %7 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
- %add.2 = mul i32 %indvars.2, %7
- %arrayidx.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.1
+ %6 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
+ %add.2 = mul i32 %indvars.2, %6
+ %arrayidx.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.1
store i32 %add.2, ptr %arrayidx.2, align 8, !tbaa !4
%indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
%indvars.3 = trunc i64 %indvars.iv.next.3 to i32
- %8 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
- %add.3 = mul i32 %indvars.3, %8
- %arrayidx.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.2
+ %7 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
+ %add.3 = mul i32 %indvars.3, %7
+ %arrayidx.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.2
store i32 %add.3, ptr %arrayidx.3, align 4, !tbaa !4
%niter.next.3 = add i64 %niter, 4
%niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
if.then: ; preds = %for.cond.cleanup
- %puts75 = call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
- %9 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
- %cmp7 = icmp eq i32 %9, 0
- br i1 %cmp7, label %if.then9, label %if.else
-
-if.then9: ; preds = %if.then
- %puts80 = call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
- call void @func4()
+ %puts77 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %8 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %8, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
unreachable
if.else: ; preds = %if.then
- %puts76 = call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
- %10 = load i32, ptr %len, align 4, !tbaa !4
- %cmp1486 = icmp sgt i32 %10, 0
- br i1 %cmp1486, label %for.body17, label %for.cond.cleanup28
-
-for.cond25.preheader: ; preds = %for.body17
- %cmp2688 = icmp sgt i32 %13, 0
- br i1 %cmp2688, label %for.body29.preheader, label %for.cond.cleanup28
-
-for.body29.preheader: ; preds = %for.cond25.preheader
- %wide.trip.count104 = zext nneg i32 %13 to i64
- %xtraiter108 = and i64 %wide.trip.count104, 3
- %11 = icmp ult i32 %13, 4
- br i1 %11, label %for.cond.cleanup28.loopexit.unr-lcssa, label %for.body29.preheader.new
-
-for.body29.preheader.new: ; preds = %for.body29.preheader
- %unroll_iter111 = and i64 %wide.trip.count104, 2147483644
- br label %for.body29
-
-for.body17: ; preds = %if.else, %for.body17
- %indvars.iv96 = phi i64 [ %indvars.iv.next97, %for.body17 ], [ 0, %if.else ]
- %arrayidx19 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv96
- %12 = load i32, ptr %arrayidx19, align 4, !tbaa !4
- %call20 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %12)
- %indvars.iv.next97 = add nuw nsw i64 %indvars.iv96, 1
- %13 = load i32, ptr %len, align 4, !tbaa !4
- %14 = sext i32 %13 to i64
- %cmp14 = icmp slt i64 %indvars.iv.next97, %14
- br i1 %cmp14, label %for.body17, label %for.cond25.preheader, !llvm.loop !12
-
-for.cond.cleanup28.loopexit.unr-lcssa: ; preds = %for.body29, %for.body29.preheader
- %indvars.iv100.unr = phi i64 [ 0, %for.body29.preheader ], [ %indvars.iv.next101.3, %for.body29 ]
- %lcmp.mod110.not = icmp eq i64 %xtraiter108, 0
- br i1 %lcmp.mod110.not, label %for.cond.cleanup28, label %for.body29.epil
-
-for.body29.epil: ; preds = %for.cond.cleanup28.loopexit.unr-lcssa, %for.body29.epil
- %indvars.iv100.epil = phi i64 [ %indvars.iv.next101.epil, %for.body29.epil ], [ %indvars.iv100.unr, %for.cond.cleanup28.loopexit.unr-lcssa ]
- %epil.iter109 = phi i64 [ %epil.iter109.next, %for.body29.epil ], [ 0, %for.cond.cleanup28.loopexit.unr-lcssa ]
- %indvars.iv.next101.epil = add nuw nsw i64 %indvars.iv100.epil, 1
- %indvars102.epil = trunc i64 %indvars.iv.next101.epil to i32
- %15 = trunc nuw nsw i64 %indvars.iv100.epil to i32
- %mul3177.epil = mul i32 %indvars102.epil, %15
- %add3379.epil = add nuw nsw i32 %mul3177.epil, 1
- %add34.epil = mul i32 %add3379.epil, %15
- %arrayidx36.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv100.epil
- store i32 %add34.epil, ptr %arrayidx36.epil, align 4, !tbaa !4
- %epil.iter109.next = add i64 %epil.iter109, 1
- %epil.iter109.cmp.not = icmp eq i64 %epil.iter109.next, %xtraiter108
- br i1 %epil.iter109.cmp.not, label %for.cond.cleanup28, label %for.body29.epil, !llvm.loop !13
-
-for.cond.cleanup28: ; preds = %for.cond.cleanup28.loopexit.unr-lcssa, %for.body29.epil, %if.else, %for.cond25.preheader
- call void @func3()
+ %puts78 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ br i1 %cmp84, label %for.body15.preheader, label %for.cond.cleanup26
+
+for.body15.preheader: ; preds = %if.else
+ %wide.trip.count103 = zext nneg i32 %len to i64
+ br label %for.body15
+
+for.body27.preheader: ; preds = %for.body15
+ %xtraiter111 = and i64 %wide.trip.count103, 3
+ %9 = icmp ult i32 %len, 4
+ br i1 %9, label %for.cond.cleanup26.loopexit.unr-lcssa, label %for.body27.preheader.new
+
+for.body27.preheader.new: ; preds = %for.body27.preheader
+ %unroll_iter114 = and i64 %wide.trip.count103, 2147483644
+ br label %for.body27
+
+for.body15: ; preds = %for.body15.preheader, %for.body15
+ %indvars.iv99 = phi i64 [ 0, %for.body15.preheader ], [ %indvars.iv.next100, %for.body15 ]
+ %arrayidx17 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv99
+ %10 = load i32, ptr %arrayidx17, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %10)
+ %indvars.iv.next100 = add nuw nsw i64 %indvars.iv99, 1
+ %exitcond104.not = icmp eq i64 %indvars.iv.next100, %wide.trip.count103
+ br i1 %exitcond104.not, label %for.body27.preheader, label %for.body15, !llvm.loop !12
+
+for.cond.cleanup26.loopexit.unr-lcssa: ; preds = %for.body27, %for.body27.preheader
+ %indvars.iv105.unr = phi i64 [ 0, %for.body27.preheader ], [ %indvars.iv.next106.3, %for.body27 ]
+ %lcmp.mod113.not = icmp eq i64 %xtraiter111, 0
+ br i1 %lcmp.mod113.not, label %for.cond.cleanup26, label %for.body27.epil
+
+for.body27.epil: ; preds = %for.cond.cleanup26.loopexit.unr-lcssa, %for.body27.epil
+ %indvars.iv105.epil = phi i64 [ %indvars.iv.next106.epil, %for.body27.epil ], [ %indvars.iv105.unr, %for.cond.cleanup26.loopexit.unr-lcssa ]
+ %epil.iter112 = phi i64 [ %epil.iter112.next, %for.body27.epil ], [ 0, %for.cond.cleanup26.loopexit.unr-lcssa ]
+ %indvars.iv.next106.epil = add nuw nsw i64 %indvars.iv105.epil, 1
+ %indvars107.epil = trunc i64 %indvars.iv.next106.epil to i32
+ %11 = trunc nuw nsw i64 %indvars.iv105.epil to i32
+ %mul2979.epil = mul i32 %indvars107.epil, %11
+ %add3181.epil = add nuw nsw i32 %mul2979.epil, 1
+ %add32.epil = mul i32 %add3181.epil, %11
+ %arrayidx34.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv105.epil
+ store i32 %add32.epil, ptr %arrayidx34.epil, align 4, !tbaa !4
+ %epil.iter112.next = add i64 %epil.iter112, 1
+ %epil.iter112.cmp.not = icmp eq i64 %epil.iter112.next, %xtraiter111
+ br i1 %epil.iter112.cmp.not, label %for.cond.cleanup26, label %for.body27.epil, !llvm.loop !13
+
+for.cond.cleanup26: ; preds = %for.cond.cleanup26.loopexit.unr-lcssa, %for.body27.epil, %if.else
+ tail call void @func3()
unreachable
-for.body29: ; preds = %for.body29, %for.body29.preheader.new
- %indvars.iv100 = phi i64 [ 0, %for.body29.preheader.new ], [ %indvars.iv.next101.3, %for.body29 ]
- %niter112 = phi i64 [ 0, %for.body29.preheader.new ], [ %niter112.next.3, %for.body29 ]
- %indvars.iv.next101 = or disjoint i64 %indvars.iv100, 1
- %indvars102 = trunc i64 %indvars.iv.next101 to i32
- %16 = trunc nuw nsw i64 %indvars.iv100 to i32
- %mul3177 = mul i32 %indvars102, %16
- %add3379 = or disjoint i32 %mul3177, 1
- %add34 = mul i32 %add3379, %16
- %arrayidx36 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv100
- store i32 %add34, ptr %arrayidx36, align 8, !tbaa !4
- %indvars.iv.next101.1 = or disjoint i64 %indvars.iv100, 2
- %indvars102.1 = trunc i64 %indvars.iv.next101.1 to i32
- %17 = trunc nuw nsw i64 %indvars.iv.next101 to i32
- %mul3177.1 = mul i32 %indvars102.1, %17
- %add3379.1 = or disjoint i32 %mul3177.1, 1
- %add34.1 = mul i32 %add3379.1, %17
- %arrayidx36.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101
- store i32 %add34.1, ptr %arrayidx36.1, align 4, !tbaa !4
- %indvars.iv.next101.2 = or disjoint i64 %indvars.iv100, 3
- %indvars102.2 = trunc i64 %indvars.iv.next101.2 to i32
- %18 = trunc nuw nsw i64 %indvars.iv.next101.1 to i32
- %mul3177.2 = mul i32 %indvars102.2, %18
- %add3379.2 = or disjoint i32 %mul3177.2, 1
- %add34.2 = mul i32 %add3379.2, %18
- %arrayidx36.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101.1
- store i32 %add34.2, ptr %arrayidx36.2, align 8, !tbaa !4
- %indvars.iv.next101.3 = add nuw nsw i64 %indvars.iv100, 4
- %indvars102.3 = trunc i64 %indvars.iv.next101.3 to i32
- %19 = trunc nuw nsw i64 %indvars.iv.next101.2 to i32
- %mul3177.3 = mul i32 %indvars102.3, %19
- %add3379.3 = or disjoint i32 %mul3177.3, 1
- %add34.3 = mul i32 %add3379.3, %19
- %arrayidx36.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101.2
- store i32 %add34.3, ptr %arrayidx36.3, align 4, !tbaa !4
- %niter112.next.3 = add i64 %niter112, 4
- %niter112.ncmp.3 = icmp eq i64 %niter112.next.3, %unroll_iter111
- br i1 %niter112.ncmp.3, label %for.cond.cleanup28.loopexit.unr-lcssa, label %for.body29, !llvm.loop !14
-
-if.else40: ; preds = %for.cond.cleanup
- %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
- %20 = load i32, ptr %len, align 4, !tbaa !4
- %cmp4484 = icmp sgt i32 %20, 0
- br i1 %cmp4484, label %for.body47, label %for.cond.cleanup46
-
-for.cond.cleanup46: ; preds = %for.body47, %if.else40
- call void @func2()
- unreachable
+for.body27: ; preds = %for.body27, %for.body27.preheader.new
+ %indvars.iv105 = phi i64 [ 0, %for.body27.preheader.new ], [ %indvars.iv.next106.3, %for.body27 ]
+ %niter115 = phi i64 [ 0, %for.body27.preheader.new ], [ %niter115.next.3, %for.body27 ]
+ %indvars.iv.next106 = or disjoint i64 %indvars.iv105, 1
+ %indvars107 = trunc i64 %indvars.iv.next106 to i32
+ %12 = trunc nuw nsw i64 %indvars.iv105 to i32
+ %mul2979 = mul i32 %indvars107, %12
+ %add3181 = or disjoint i32 %mul2979, 1
+ %add32 = mul i32 %add3181, %12
+ %arrayidx34 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv105
+ store i32 %add32, ptr %arrayidx34, align 8, !tbaa !4
+ %indvars.iv.next106.1 = or disjoint i64 %indvars.iv105, 2
+ %indvars107.1 = trunc i64 %indvars.iv.next106.1 to i32
+ %13 = trunc nuw nsw i64 %indvars.iv.next106 to i32
+ %mul2979.1 = mul i32 %indvars107.1, %13
+ %add3181.1 = or disjoint i32 %mul2979.1, 1
+ %add32.1 = mul i32 %add3181.1, %13
+ %arrayidx34.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106
+ store i32 %add32.1, ptr %arrayidx34.1, align 4, !tbaa !4
+ %indvars.iv.next106.2 = or disjoint i64 %indvars.iv105, 3
+ %indvars107.2 = trunc i64 %indvars.iv.next106.2 to i32
+ %14 = trunc nuw nsw i64 %indvars.iv.next106.1 to i32
+ %mul2979.2 = mul i32 %indvars107.2, %14
+ %add3181.2 = or disjoint i32 %mul2979.2, 1
+ %add32.2 = mul i32 %add3181.2, %14
+ %arrayidx34.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106.1
+ store i32 %add32.2, ptr %arrayidx34.2, align 8, !tbaa !4
+ %indvars.iv.next106.3 = add nuw nsw i64 %indvars.iv105, 4
+ %indvars107.3 = trunc i64 %indvars.iv.next106.3 to i32
+ %15 = trunc nuw nsw i64 %indvars.iv.next106.2 to i32
+ %mul2979.3 = mul i32 %indvars107.3, %15
+ %add3181.3 = or disjoint i32 %mul2979.3, 1
+ %add32.3 = mul i32 %add3181.3, %15
+ %arrayidx34.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106.2
+ store i32 %add32.3, ptr %arrayidx34.3, align 4, !tbaa !4
+ %niter115.next.3 = add i64 %niter115, 4
+ %niter115.ncmp.3 = icmp eq i64 %niter115.next.3, %unroll_iter114
+ br i1 %niter115.ncmp.3, label %for.cond.cleanup26.loopexit.unr-lcssa, label %for.body27, !llvm.loop !14
+
+if.else38: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ br i1 %cmp84, label %for.body45.preheader, label %for.cond.cleanup44
-for.body47: ; preds = %if.else40, %for.body47
- %indvars.iv92 = phi i64 [ %indvars.iv.next93, %for.body47 ], [ 0, %if.else40 ]
- %arrayidx49 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv92
- %21 = load i32, ptr %arrayidx49, align 4, !tbaa !4
- %call50 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %21)
- %indvars.iv.next93 = add nuw nsw i64 %indvars.iv92, 1
- %22 = load i32, ptr %len, align 4, !tbaa !4
- %23 = sext i32 %22 to i64
- %cmp44 = icmp slt i64 %indvars.iv.next93, %23
- br i1 %cmp44, label %for.body47, label %for.cond.cleanup46, !llvm.loop !15
-}
+for.body45.preheader: ; preds = %if.else38
+ %wide.trip.count97 = zext nneg i32 %len to i64
+ br label %for.body45
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
-declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
+for.cond.cleanup44: ; preds = %for.body45, %if.else38
+ tail call void @func2()
+ unreachable
-; Function Attrs: nofree nounwind
-declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+for.body45: ; preds = %for.body45.preheader, %for.body45
+ %indvars.iv93 = phi i64 [ 0, %for.body45.preheader ], [ %indvars.iv.next94, %for.body45 ]
+ %arrayidx47 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv93
+ %16 = load i32, ptr %arrayidx47, align 4, !tbaa !4
+ %call48 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %16)
+ %indvars.iv.next94 = add nuw nsw i64 %indvars.iv93, 1
+ %exitcond98.not = icmp eq i64 %indvars.iv.next94, %wide.trip.count97
+ br i1 %exitcond98.not, label %for.cond.cleanup44, label %for.body45, !llvm.loop !15
+}
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
; Function Attrs: nounwind
-define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
entry:
%0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
%cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
- %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
- %call1 = tail call signext i32 @func1()
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %1 = load i32, ptr @len, align 4, !tbaa !4
+ %call1 = tail call signext i32 @func1(i32 noundef signext %1)
unreachable
if.else: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
ret i32 0
}
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #2 = { noreturn nounwind }
attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-attributes #5 = { nounwind }
-attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #7 = { nofree nounwind }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -315,7 +314,7 @@ attributes #7 = { nofree nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
!4 = !{!5, !5, i64 0}
!5 = !{!"int", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-03.ll
index d68bf7a9838489..d30aa13dbca79c 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-03.ll
@@ -1,12 +1,9 @@
+; This test case produces right result when alloca len is not local variable.
+; Test output of setjmp/longjmp with nested setjmp for alloca
; Test for Frame Pointer in first slot in jmp_buf.
-; Test assembly for nested setjmp for alloa with switch statement.
-; This test case takes input from stdin for size of alloca
-; and produce the right result.
-; Frame Pointer in slot 1.
-; Return address in slot 2.
-; Stack Pointer in slot 4.
-; RUN: llc < %s | FileCheck %s
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
; ModuleID = 'builtin-setjmp-longjmp-alloca-03.c'
source_filename = "builtin-setjmp-longjmp-alloca-03.c"
@@ -16,23 +13,22 @@ target triple = "s390x-unknown-linux-gnu"
@buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
- at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
- at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
- at .str.13 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at len = dso_local local_unnamed_addr global i32 10, align 4
+ at .str.11 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
@str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
- at str.17 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
- at str.18 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
- at str.19 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
- at str.20 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
- at str.21 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
- at str.27 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
- at str.28 = private unnamed_addr constant [8 x i8] c"case 4:\00", align 1
- at str.29 = private unnamed_addr constant [8 x i8] c"case 3:\00", align 1
- at str.30 = private unnamed_addr constant [8 x i8] c"case 2:\00", align 1
- at str.31 = private unnamed_addr constant [8 x i8] c"case 1:\00", align 1
- at str.32 = private unnamed_addr constant [8 x i8] c"case 0:\00", align 1
- at str.33 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
- at str.34 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.15 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.16 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.18 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.25 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.26 = private unnamed_addr constant [8 x i8] c"case 4:\00", align 1
+ at str.27 = private unnamed_addr constant [8 x i8] c"case 3:\00", align 1
+ at str.28 = private unnamed_addr constant [8 x i8] c"case 2:\00", align 1
+ at str.29 = private unnamed_addr constant [8 x i8] c"case 1:\00", align 1
+ at str.30 = private unnamed_addr constant [8 x i8] c"case 0:\00", align 1
+ at str.31 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.32 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
; Function Attrs: noinline noreturn nounwind
define dso_local void @func4() local_unnamed_addr #0 {
@@ -51,7 +47,7 @@ declare void @llvm.eh.sjlj.longjmp(ptr) #2
; Function Attrs: noinline noreturn nounwind
define dso_local void @func3() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
unreachable
}
@@ -59,7 +55,7 @@ entry:
; Function Attrs: noinline noreturn nounwind
define dso_local void @func2() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
unreachable
}
@@ -67,17 +63,12 @@ entry:
; Function Attrs: noreturn nounwind
define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
entry:
- %len = alloca i32, align 4
- call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
- store i32 10, ptr %len, align 4, !tbaa !4
- %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
- %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
- %0 = load i32, ptr %len, align 4, !tbaa !4
+ %0 = load i32, ptr @len, align 4, !tbaa !4
%conv = sext i32 %0 to i64
%mul = shl nsw i64 %conv, 2
%1 = alloca i8, i64 %mul, align 8
- %cmp350 = icmp sgt i32 %0, 0
- br i1 %cmp350, label %for.body.preheader, label %for.cond.cleanup
+ %cmp348 = icmp sgt i32 %0, 0
+ br i1 %cmp348, label %for.body.preheader, label %for.cond.cleanup
for.body.preheader: ; preds = %entry
%wide.trip.count = zext nneg i32 %0 to i64
@@ -108,9 +99,36 @@ for.body.epil: ; preds = %for.cond.cleanup.lo
br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
- %4 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
- %cmp4 = icmp eq i32 %4, 0
- br i1 %cmp4, label %if.then, label %if.else202
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: case 0:
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 4
+; CHECK: arr: 10
+; CHECK: arr: 18
+; CHECK: arr: 28
+; CHECK: arr: 40
+; CHECK: arr: 54
+; CHECK: arr: 70
+; CHECK: arr: 88
+; CHECK: arr: 108
+; CHECK: case 0:
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 5
+; CHECK: arr: 26
+; CHECK: arr: 99
+; CHECK: arr: 284
+; CHECK: arr: 665
+; CHECK: arr: 1350
+; CHECK: arr: 2471
+; CHECK: arr: 4184
+; CHECK: arr: 6669
+
+ %4 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %4, 0
+ br i1 %cmp3, label %if.then, label %if.else200
for.body: ; preds = %for.body, %for.body.preheader.new
%indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
@@ -144,853 +162,841 @@ for.body: ; preds = %for.body, %for.body
br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
if.then: ; preds = %for.cond.cleanup
- %puts307 = call i32 @puts(ptr nonnull dereferenceable(1) @str.20)
- %9 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
- %cmp7 = icmp eq i32 %9, 0
- br i1 %cmp7, label %if.then9, label %if.else
-
-if.then9: ; preds = %if.then
- %puts324 = call i32 @puts(ptr nonnull dereferenceable(1) @str.27)
- %10 = load i32, ptr %len, align 4, !tbaa !4
+ %puts305 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %9 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %9, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts322 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.25)
+ %10 = load i32, ptr @len, align 4, !tbaa !4
%rem = srem i32 %10, 5
switch i32 %rem, label %sw.epilog [
i32 0, label %sw.bb
- i32 1, label %sw.bb26
- i32 2, label %sw.bb45
- i32 3, label %sw.bb63
- i32 4, label %sw.bb79
+ i32 1, label %sw.bb24
+ i32 2, label %sw.bb43
+ i32 3, label %sw.bb61
+ i32 4, label %sw.bb77
]
-sw.bb: ; preds = %if.then9
- %puts339 = call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
- %11 = load i32, ptr %len, align 4, !tbaa !4
- %cmp14374 = icmp sgt i32 %11, 0
- br i1 %cmp14374, label %for.body17.preheader, label %sw.epilog
+sw.bb: ; preds = %if.then7
+ %puts337 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
+ %11 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp12372 = icmp sgt i32 %11, 0
+ br i1 %cmp12372, label %for.body15.preheader, label %sw.epilog
-for.body17.preheader: ; preds = %sw.bb
- %wide.trip.count460 = zext nneg i32 %11 to i64
- %xtraiter534 = and i64 %wide.trip.count460, 3
+for.body15.preheader: ; preds = %sw.bb
+ %wide.trip.count458 = zext nneg i32 %11 to i64
+ %xtraiter532 = and i64 %wide.trip.count458, 3
%12 = icmp ult i32 %11, 4
- br i1 %12, label %sw.epilog.loopexit.unr-lcssa, label %for.body17.preheader.new
-
-for.body17.preheader.new: ; preds = %for.body17.preheader
- %unroll_iter537 = and i64 %wide.trip.count460, 2147483644
- br label %for.body17
-
-for.body17: ; preds = %for.body17, %for.body17.preheader.new
- %indvars.iv455 = phi i64 [ 0, %for.body17.preheader.new ], [ %indvars.iv.next456.3, %for.body17 ]
- %niter538 = phi i64 [ 0, %for.body17.preheader.new ], [ %niter538.next.3, %for.body17 ]
- %indvars459 = trunc i64 %indvars.iv455 to i32
- %mul19340 = or disjoint i32 %indvars459, 3
- %add20 = mul i32 %mul19340, %indvars459
- %arrayidx22 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv455
- store i32 %add20, ptr %arrayidx22, align 8, !tbaa !4
- %indvars.iv.next456 = or disjoint i64 %indvars.iv455, 1
- %indvars459.1 = trunc i64 %indvars.iv.next456 to i32
- %mul19340.1 = add nuw i32 %indvars459.1, 3
- %add20.1 = mul i32 %mul19340.1, %indvars459.1
- %arrayidx22.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456
- store i32 %add20.1, ptr %arrayidx22.1, align 4, !tbaa !4
- %indvars.iv.next456.1 = or disjoint i64 %indvars.iv455, 2
- %indvars459.2 = trunc i64 %indvars.iv.next456.1 to i32
- %mul19340.2 = add nuw i32 %indvars459.2, 3
- %add20.2 = mul i32 %mul19340.2, %indvars459.2
- %arrayidx22.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456.1
- store i32 %add20.2, ptr %arrayidx22.2, align 8, !tbaa !4
- %indvars.iv.next456.2 = or disjoint i64 %indvars.iv455, 3
- %indvars459.3 = trunc i64 %indvars.iv.next456.2 to i32
- %mul19340.3 = add nuw i32 %indvars459.3, 3
- %add20.3 = mul i32 %mul19340.3, %indvars459.3
- %arrayidx22.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456.2
- store i32 %add20.3, ptr %arrayidx22.3, align 4, !tbaa !4
- %indvars.iv.next456.3 = add nuw nsw i64 %indvars.iv455, 4
- %niter538.next.3 = add i64 %niter538, 4
- %niter538.ncmp.3 = icmp eq i64 %niter538.next.3, %unroll_iter537
- br i1 %niter538.ncmp.3, label %sw.epilog.loopexit.unr-lcssa, label %for.body17, !llvm.loop !12
-
-sw.bb26: ; preds = %if.then9
- %puts335 = call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
- %13 = load i32, ptr %len, align 4, !tbaa !4
- %cmp30372 = icmp sgt i32 %13, 0
- br i1 %cmp30372, label %for.body33.preheader, label %sw.epilog
-
-for.body33.preheader: ; preds = %sw.bb26
- %wide.trip.count453 = zext nneg i32 %13 to i64
- %xtraiter529 = and i64 %wide.trip.count453, 3
+ br i1 %12, label %sw.epilog.loopexit.unr-lcssa, label %for.body15.preheader.new
+
+for.body15.preheader.new: ; preds = %for.body15.preheader
+ %unroll_iter535 = and i64 %wide.trip.count458, 2147483644
+ br label %for.body15
+
+for.body15: ; preds = %for.body15, %for.body15.preheader.new
+ %indvars.iv453 = phi i64 [ 0, %for.body15.preheader.new ], [ %indvars.iv.next454.3, %for.body15 ]
+ %niter536 = phi i64 [ 0, %for.body15.preheader.new ], [ %niter536.next.3, %for.body15 ]
+ %indvars457 = trunc i64 %indvars.iv453 to i32
+ %mul17338 = or disjoint i32 %indvars457, 3
+ %add18 = mul i32 %mul17338, %indvars457
+ %arrayidx20 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv453
+ store i32 %add18, ptr %arrayidx20, align 8, !tbaa !4
+ %indvars.iv.next454 = or disjoint i64 %indvars.iv453, 1
+ %indvars457.1 = trunc i64 %indvars.iv.next454 to i32
+ %mul17338.1 = add nuw i32 %indvars457.1, 3
+ %add18.1 = mul i32 %mul17338.1, %indvars457.1
+ %arrayidx20.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next454
+ store i32 %add18.1, ptr %arrayidx20.1, align 4, !tbaa !4
+ %indvars.iv.next454.1 = or disjoint i64 %indvars.iv453, 2
+ %indvars457.2 = trunc i64 %indvars.iv.next454.1 to i32
+ %mul17338.2 = add nuw i32 %indvars457.2, 3
+ %add18.2 = mul i32 %mul17338.2, %indvars457.2
+ %arrayidx20.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next454.1
+ store i32 %add18.2, ptr %arrayidx20.2, align 8, !tbaa !4
+ %indvars.iv.next454.2 = or disjoint i64 %indvars.iv453, 3
+ %indvars457.3 = trunc i64 %indvars.iv.next454.2 to i32
+ %mul17338.3 = add nuw i32 %indvars457.3, 3
+ %add18.3 = mul i32 %mul17338.3, %indvars457.3
+ %arrayidx20.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next454.2
+ store i32 %add18.3, ptr %arrayidx20.3, align 4, !tbaa !4
+ %indvars.iv.next454.3 = add nuw nsw i64 %indvars.iv453, 4
+ %niter536.next.3 = add i64 %niter536, 4
+ %niter536.ncmp.3 = icmp eq i64 %niter536.next.3, %unroll_iter535
+ br i1 %niter536.ncmp.3, label %sw.epilog.loopexit.unr-lcssa, label %for.body15, !llvm.loop !12
+
+sw.bb24: ; preds = %if.then7
+ %puts333 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
+ %13 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp28370 = icmp sgt i32 %13, 0
+ br i1 %cmp28370, label %for.body31.preheader, label %sw.epilog
+
+for.body31.preheader: ; preds = %sw.bb24
+ %wide.trip.count451 = zext nneg i32 %13 to i64
+ %xtraiter527 = and i64 %wide.trip.count451, 3
%14 = icmp ult i32 %13, 4
- br i1 %14, label %sw.epilog.loopexit480.unr-lcssa, label %for.body33.preheader.new
-
-for.body33.preheader.new: ; preds = %for.body33.preheader
- %unroll_iter532 = and i64 %wide.trip.count453, 2147483644
- br label %for.body33
-
-for.body33: ; preds = %for.body33, %for.body33.preheader.new
- %indvars.iv449 = phi i64 [ 0, %for.body33.preheader.new ], [ %indvars.iv.next450.3, %for.body33 ]
- %niter533 = phi i64 [ 0, %for.body33.preheader.new ], [ %niter533.next.3, %for.body33 ]
- %indvars.iv.next450 = or disjoint i64 %indvars.iv449, 1
- %indvars451 = trunc i64 %indvars.iv.next450 to i32
- %15 = trunc nuw nsw i64 %indvars.iv449 to i32
- %mul35336 = mul i32 %indvars451, %15
- %add37338 = or disjoint i32 %mul35336, 3
- %add39 = mul i32 %add37338, %15
- %arrayidx41 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv449
- store i32 %add39, ptr %arrayidx41, align 8, !tbaa !4
- %indvars.iv.next450.1 = or disjoint i64 %indvars.iv449, 2
- %indvars451.1 = trunc i64 %indvars.iv.next450.1 to i32
- %16 = trunc nuw nsw i64 %indvars.iv.next450 to i32
- %mul35336.1 = mul i32 %indvars451.1, %16
- %add37338.1 = add i32 %mul35336.1, 3
- %add39.1 = mul i32 %add37338.1, %16
- %arrayidx41.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450
- store i32 %add39.1, ptr %arrayidx41.1, align 4, !tbaa !4
- %indvars.iv.next450.2 = or disjoint i64 %indvars.iv449, 3
- %indvars451.2 = trunc i64 %indvars.iv.next450.2 to i32
- %17 = trunc nuw nsw i64 %indvars.iv.next450.1 to i32
- %mul35336.2 = mul i32 %indvars451.2, %17
- %add37338.2 = add i32 %mul35336.2, 3
- %add39.2 = mul i32 %add37338.2, %17
- %arrayidx41.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450.1
- store i32 %add39.2, ptr %arrayidx41.2, align 8, !tbaa !4
- %indvars.iv.next450.3 = add nuw nsw i64 %indvars.iv449, 4
- %indvars451.3 = trunc i64 %indvars.iv.next450.3 to i32
- %18 = trunc nuw nsw i64 %indvars.iv.next450.2 to i32
- %mul35336.3 = mul i32 %indvars451.3, %18
- %add37338.3 = or disjoint i32 %mul35336.3, 3
- %add39.3 = mul i32 %add37338.3, %18
- %arrayidx41.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450.2
- store i32 %add39.3, ptr %arrayidx41.3, align 4, !tbaa !4
- %niter533.next.3 = add i64 %niter533, 4
- %niter533.ncmp.3 = icmp eq i64 %niter533.next.3, %unroll_iter532
- br i1 %niter533.ncmp.3, label %sw.epilog.loopexit480.unr-lcssa, label %for.body33, !llvm.loop !13
-
-sw.bb45: ; preds = %if.then9
- %puts331 = call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
- %19 = load i32, ptr %len, align 4, !tbaa !4
- %cmp49370 = icmp sgt i32 %19, 0
- br i1 %cmp49370, label %for.body52.preheader, label %sw.epilog
-
-for.body52.preheader: ; preds = %sw.bb45
- %wide.trip.count447 = zext nneg i32 %19 to i64
- %xtraiter524 = and i64 %wide.trip.count447, 3
+ br i1 %14, label %sw.epilog.loopexit478.unr-lcssa, label %for.body31.preheader.new
+
+for.body31.preheader.new: ; preds = %for.body31.preheader
+ %unroll_iter530 = and i64 %wide.trip.count451, 2147483644
+ br label %for.body31
+
+for.body31: ; preds = %for.body31, %for.body31.preheader.new
+ %indvars.iv447 = phi i64 [ 0, %for.body31.preheader.new ], [ %indvars.iv.next448.3, %for.body31 ]
+ %niter531 = phi i64 [ 0, %for.body31.preheader.new ], [ %niter531.next.3, %for.body31 ]
+ %indvars.iv.next448 = or disjoint i64 %indvars.iv447, 1
+ %indvars449 = trunc i64 %indvars.iv.next448 to i32
+ %15 = trunc nuw nsw i64 %indvars.iv447 to i32
+ %mul33334 = mul i32 %indvars449, %15
+ %add35336 = or disjoint i32 %mul33334, 3
+ %add37 = mul i32 %add35336, %15
+ %arrayidx39 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv447
+ store i32 %add37, ptr %arrayidx39, align 8, !tbaa !4
+ %indvars.iv.next448.1 = or disjoint i64 %indvars.iv447, 2
+ %indvars449.1 = trunc i64 %indvars.iv.next448.1 to i32
+ %16 = trunc nuw nsw i64 %indvars.iv.next448 to i32
+ %mul33334.1 = mul i32 %indvars449.1, %16
+ %add35336.1 = add i32 %mul33334.1, 3
+ %add37.1 = mul i32 %add35336.1, %16
+ %arrayidx39.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next448
+ store i32 %add37.1, ptr %arrayidx39.1, align 4, !tbaa !4
+ %indvars.iv.next448.2 = or disjoint i64 %indvars.iv447, 3
+ %indvars449.2 = trunc i64 %indvars.iv.next448.2 to i32
+ %17 = trunc nuw nsw i64 %indvars.iv.next448.1 to i32
+ %mul33334.2 = mul i32 %indvars449.2, %17
+ %add35336.2 = add i32 %mul33334.2, 3
+ %add37.2 = mul i32 %add35336.2, %17
+ %arrayidx39.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next448.1
+ store i32 %add37.2, ptr %arrayidx39.2, align 8, !tbaa !4
+ %indvars.iv.next448.3 = add nuw nsw i64 %indvars.iv447, 4
+ %indvars449.3 = trunc i64 %indvars.iv.next448.3 to i32
+ %18 = trunc nuw nsw i64 %indvars.iv.next448.2 to i32
+ %mul33334.3 = mul i32 %indvars449.3, %18
+ %add35336.3 = or disjoint i32 %mul33334.3, 3
+ %add37.3 = mul i32 %add35336.3, %18
+ %arrayidx39.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next448.2
+ store i32 %add37.3, ptr %arrayidx39.3, align 4, !tbaa !4
+ %niter531.next.3 = add i64 %niter531, 4
+ %niter531.ncmp.3 = icmp eq i64 %niter531.next.3, %unroll_iter530
+ br i1 %niter531.ncmp.3, label %sw.epilog.loopexit478.unr-lcssa, label %for.body31, !llvm.loop !13
+
+sw.bb43: ; preds = %if.then7
+ %puts329 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
+ %19 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp47368 = icmp sgt i32 %19, 0
+ br i1 %cmp47368, label %for.body50.preheader, label %sw.epilog
+
+for.body50.preheader: ; preds = %sw.bb43
+ %wide.trip.count445 = zext nneg i32 %19 to i64
+ %xtraiter522 = and i64 %wide.trip.count445, 3
%20 = icmp ult i32 %19, 4
- br i1 %20, label %sw.epilog.loopexit481.unr-lcssa, label %for.body52.preheader.new
-
-for.body52.preheader.new: ; preds = %for.body52.preheader
- %unroll_iter527 = and i64 %wide.trip.count447, 2147483644
- br label %for.body52
-
-for.body52: ; preds = %for.body52, %for.body52.preheader.new
- %indvars.iv442 = phi i64 [ 0, %for.body52.preheader.new ], [ %indvars.iv.next443.3, %for.body52 ]
- %niter528 = phi i64 [ 0, %for.body52.preheader.new ], [ %niter528.next.3, %for.body52 ]
- %indvars446 = trunc i64 %indvars.iv442 to i32
- %i47.0333 = add nsw i32 %indvars446, -1
- %mul54332 = mul i32 %i47.0333, %indvars446
- %sub334 = or disjoint i32 %mul54332, 3
- %add57 = mul i32 %sub334, %indvars446
- %arrayidx59 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv442
- store i32 %add57, ptr %arrayidx59, align 8, !tbaa !4
- %indvars.iv.next443 = or disjoint i64 %indvars.iv442, 1
- %indvars446.1 = trunc i64 %indvars.iv.next443 to i32
- %i47.0333.1 = add nsw i32 %indvars446.1, -1
- %mul54332.1 = mul i32 %i47.0333.1, %indvars446.1
- %sub334.1 = or disjoint i32 %mul54332.1, 3
- %add57.1 = mul i32 %sub334.1, %indvars446.1
- %arrayidx59.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443
- store i32 %add57.1, ptr %arrayidx59.1, align 4, !tbaa !4
- %indvars.iv.next443.1 = or disjoint i64 %indvars.iv442, 2
- %indvars446.2 = trunc i64 %indvars.iv.next443.1 to i32
- %i47.0333.2 = add nsw i32 %indvars446.2, -1
- %mul54332.2 = mul i32 %i47.0333.2, %indvars446.2
- %sub334.2 = add i32 %mul54332.2, 3
- %add57.2 = mul i32 %sub334.2, %indvars446.2
- %arrayidx59.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443.1
- store i32 %add57.2, ptr %arrayidx59.2, align 8, !tbaa !4
- %indvars.iv.next443.2 = or disjoint i64 %indvars.iv442, 3
- %indvars446.3 = trunc i64 %indvars.iv.next443.2 to i32
- %i47.0333.3 = add nsw i32 %indvars446.3, -1
- %mul54332.3 = mul i32 %i47.0333.3, %indvars446.3
- %sub334.3 = add i32 %mul54332.3, 3
- %add57.3 = mul i32 %sub334.3, %indvars446.3
- %arrayidx59.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443.2
- store i32 %add57.3, ptr %arrayidx59.3, align 4, !tbaa !4
- %indvars.iv.next443.3 = add nuw nsw i64 %indvars.iv442, 4
- %niter528.next.3 = add i64 %niter528, 4
- %niter528.ncmp.3 = icmp eq i64 %niter528.next.3, %unroll_iter527
- br i1 %niter528.ncmp.3, label %sw.epilog.loopexit481.unr-lcssa, label %for.body52, !llvm.loop !14
-
-sw.bb63: ; preds = %if.then9
- %puts329 = call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
- %21 = load i32, ptr %len, align 4, !tbaa !4
- %cmp67368 = icmp sgt i32 %21, 0
- br i1 %cmp67368, label %for.body70.preheader, label %sw.epilog
-
-for.body70.preheader: ; preds = %sw.bb63
- %wide.trip.count440 = zext nneg i32 %21 to i64
- %xtraiter519 = and i64 %wide.trip.count440, 3
+ br i1 %20, label %sw.epilog.loopexit479.unr-lcssa, label %for.body50.preheader.new
+
+for.body50.preheader.new: ; preds = %for.body50.preheader
+ %unroll_iter525 = and i64 %wide.trip.count445, 2147483644
+ br label %for.body50
+
+for.body50: ; preds = %for.body50, %for.body50.preheader.new
+ %indvars.iv440 = phi i64 [ 0, %for.body50.preheader.new ], [ %indvars.iv.next441.3, %for.body50 ]
+ %niter526 = phi i64 [ 0, %for.body50.preheader.new ], [ %niter526.next.3, %for.body50 ]
+ %indvars444 = trunc i64 %indvars.iv440 to i32
+ %i45.0331 = add nsw i32 %indvars444, -1
+ %mul52330 = mul i32 %i45.0331, %indvars444
+ %sub332 = or disjoint i32 %mul52330, 3
+ %add55 = mul i32 %sub332, %indvars444
+ %arrayidx57 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv440
+ store i32 %add55, ptr %arrayidx57, align 8, !tbaa !4
+ %indvars.iv.next441 = or disjoint i64 %indvars.iv440, 1
+ %indvars444.1 = trunc i64 %indvars.iv.next441 to i32
+ %i45.0331.1 = add nsw i32 %indvars444.1, -1
+ %mul52330.1 = mul i32 %i45.0331.1, %indvars444.1
+ %sub332.1 = or disjoint i32 %mul52330.1, 3
+ %add55.1 = mul i32 %sub332.1, %indvars444.1
+ %arrayidx57.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next441
+ store i32 %add55.1, ptr %arrayidx57.1, align 4, !tbaa !4
+ %indvars.iv.next441.1 = or disjoint i64 %indvars.iv440, 2
+ %indvars444.2 = trunc i64 %indvars.iv.next441.1 to i32
+ %i45.0331.2 = add nsw i32 %indvars444.2, -1
+ %mul52330.2 = mul i32 %i45.0331.2, %indvars444.2
+ %sub332.2 = add i32 %mul52330.2, 3
+ %add55.2 = mul i32 %sub332.2, %indvars444.2
+ %arrayidx57.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next441.1
+ store i32 %add55.2, ptr %arrayidx57.2, align 8, !tbaa !4
+ %indvars.iv.next441.2 = or disjoint i64 %indvars.iv440, 3
+ %indvars444.3 = trunc i64 %indvars.iv.next441.2 to i32
+ %i45.0331.3 = add nsw i32 %indvars444.3, -1
+ %mul52330.3 = mul i32 %i45.0331.3, %indvars444.3
+ %sub332.3 = add i32 %mul52330.3, 3
+ %add55.3 = mul i32 %sub332.3, %indvars444.3
+ %arrayidx57.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next441.2
+ store i32 %add55.3, ptr %arrayidx57.3, align 4, !tbaa !4
+ %indvars.iv.next441.3 = add nuw nsw i64 %indvars.iv440, 4
+ %niter526.next.3 = add i64 %niter526, 4
+ %niter526.ncmp.3 = icmp eq i64 %niter526.next.3, %unroll_iter525
+ br i1 %niter526.ncmp.3, label %sw.epilog.loopexit479.unr-lcssa, label %for.body50, !llvm.loop !14
+
+sw.bb61: ; preds = %if.then7
+ %puts327 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.27)
+ %21 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp65366 = icmp sgt i32 %21, 0
+ br i1 %cmp65366, label %for.body68.preheader, label %sw.epilog
+
+for.body68.preheader: ; preds = %sw.bb61
+ %wide.trip.count438 = zext nneg i32 %21 to i64
+ %xtraiter517 = and i64 %wide.trip.count438, 3
%22 = icmp ult i32 %21, 4
- br i1 %22, label %sw.epilog.loopexit482.unr-lcssa, label %for.body70.preheader.new
-
-for.body70.preheader.new: ; preds = %for.body70.preheader
- %unroll_iter522 = and i64 %wide.trip.count440, 2147483644
- br label %for.body70
-
-for.body70: ; preds = %for.body70, %for.body70.preheader.new
- %indvars.iv436 = phi i64 [ 0, %for.body70.preheader.new ], [ %indvars.iv.next437.3, %for.body70 ]
- %niter523 = phi i64 [ 0, %for.body70.preheader.new ], [ %niter523.next.3, %for.body70 ]
- %indvars.iv.next437 = or disjoint i64 %indvars.iv436, 1
- %indvars438 = trunc i64 %indvars.iv.next437 to i32
- %23 = trunc nuw nsw i64 %indvars.iv436 to i32
- %add72 = mul i32 %indvars438, %23
- %add73 = or disjoint i32 %add72, 3
- %arrayidx75 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv436
- store i32 %add73, ptr %arrayidx75, align 8, !tbaa !4
- %indvars.iv.next437.1 = or disjoint i64 %indvars.iv436, 2
- %indvars438.1 = trunc i64 %indvars.iv.next437.1 to i32
- %24 = trunc nuw nsw i64 %indvars.iv.next437 to i32
- %add72.1 = mul i32 %indvars438.1, %24
- %add73.1 = add nsw i32 %add72.1, 3
- %arrayidx75.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437
- store i32 %add73.1, ptr %arrayidx75.1, align 4, !tbaa !4
- %indvars.iv.next437.2 = or disjoint i64 %indvars.iv436, 3
- %indvars438.2 = trunc i64 %indvars.iv.next437.2 to i32
- %25 = trunc nuw nsw i64 %indvars.iv.next437.1 to i32
- %add72.2 = mul i32 %indvars438.2, %25
- %add73.2 = add nsw i32 %add72.2, 3
- %arrayidx75.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437.1
- store i32 %add73.2, ptr %arrayidx75.2, align 8, !tbaa !4
- %indvars.iv.next437.3 = add nuw nsw i64 %indvars.iv436, 4
- %indvars438.3 = trunc i64 %indvars.iv.next437.3 to i32
- %26 = trunc nuw nsw i64 %indvars.iv.next437.2 to i32
- %add72.3 = mul i32 %indvars438.3, %26
- %add73.3 = or disjoint i32 %add72.3, 3
- %arrayidx75.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437.2
- store i32 %add73.3, ptr %arrayidx75.3, align 4, !tbaa !4
- %niter523.next.3 = add i64 %niter523, 4
- %niter523.ncmp.3 = icmp eq i64 %niter523.next.3, %unroll_iter522
- br i1 %niter523.ncmp.3, label %sw.epilog.loopexit482.unr-lcssa, label %for.body70, !llvm.loop !15
-
-sw.bb79: ; preds = %if.then9
- %puts325 = call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
- %27 = load i32, ptr %len, align 4, !tbaa !4
- %cmp83366 = icmp sgt i32 %27, 0
- br i1 %cmp83366, label %for.body86.preheader, label %sw.epilog
-
-for.body86.preheader: ; preds = %sw.bb79
- %wide.trip.count434 = zext nneg i32 %27 to i64
- %xtraiter514 = and i64 %wide.trip.count434, 3
+ br i1 %22, label %sw.epilog.loopexit480.unr-lcssa, label %for.body68.preheader.new
+
+for.body68.preheader.new: ; preds = %for.body68.preheader
+ %unroll_iter520 = and i64 %wide.trip.count438, 2147483644
+ br label %for.body68
+
+for.body68: ; preds = %for.body68, %for.body68.preheader.new
+ %indvars.iv434 = phi i64 [ 0, %for.body68.preheader.new ], [ %indvars.iv.next435.3, %for.body68 ]
+ %niter521 = phi i64 [ 0, %for.body68.preheader.new ], [ %niter521.next.3, %for.body68 ]
+ %indvars.iv.next435 = or disjoint i64 %indvars.iv434, 1
+ %indvars436 = trunc i64 %indvars.iv.next435 to i32
+ %23 = trunc nuw nsw i64 %indvars.iv434 to i32
+ %add70 = mul i32 %indvars436, %23
+ %add71 = or disjoint i32 %add70, 3
+ %arrayidx73 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv434
+ store i32 %add71, ptr %arrayidx73, align 8, !tbaa !4
+ %indvars.iv.next435.1 = or disjoint i64 %indvars.iv434, 2
+ %indvars436.1 = trunc i64 %indvars.iv.next435.1 to i32
+ %24 = trunc nuw nsw i64 %indvars.iv.next435 to i32
+ %add70.1 = mul i32 %indvars436.1, %24
+ %add71.1 = add nsw i32 %add70.1, 3
+ %arrayidx73.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next435
+ store i32 %add71.1, ptr %arrayidx73.1, align 4, !tbaa !4
+ %indvars.iv.next435.2 = or disjoint i64 %indvars.iv434, 3
+ %indvars436.2 = trunc i64 %indvars.iv.next435.2 to i32
+ %25 = trunc nuw nsw i64 %indvars.iv.next435.1 to i32
+ %add70.2 = mul i32 %indvars436.2, %25
+ %add71.2 = add nsw i32 %add70.2, 3
+ %arrayidx73.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next435.1
+ store i32 %add71.2, ptr %arrayidx73.2, align 8, !tbaa !4
+ %indvars.iv.next435.3 = add nuw nsw i64 %indvars.iv434, 4
+ %indvars436.3 = trunc i64 %indvars.iv.next435.3 to i32
+ %26 = trunc nuw nsw i64 %indvars.iv.next435.2 to i32
+ %add70.3 = mul i32 %indvars436.3, %26
+ %add71.3 = or disjoint i32 %add70.3, 3
+ %arrayidx73.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next435.2
+ store i32 %add71.3, ptr %arrayidx73.3, align 4, !tbaa !4
+ %niter521.next.3 = add i64 %niter521, 4
+ %niter521.ncmp.3 = icmp eq i64 %niter521.next.3, %unroll_iter520
+ br i1 %niter521.ncmp.3, label %sw.epilog.loopexit480.unr-lcssa, label %for.body68, !llvm.loop !15
+
+sw.bb77: ; preds = %if.then7
+ %puts323 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.26)
+ %27 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp81364 = icmp sgt i32 %27, 0
+ br i1 %cmp81364, label %for.body84.preheader, label %sw.epilog
+
+for.body84.preheader: ; preds = %sw.bb77
+ %wide.trip.count432 = zext nneg i32 %27 to i64
+ %xtraiter512 = and i64 %wide.trip.count432, 3
%28 = icmp ult i32 %27, 4
- br i1 %28, label %sw.epilog.loopexit483.unr-lcssa, label %for.body86.preheader.new
-
-for.body86.preheader.new: ; preds = %for.body86.preheader
- %unroll_iter517 = and i64 %wide.trip.count434, 2147483644
- br label %for.body86
-
-for.body86: ; preds = %for.body86, %for.body86.preheader.new
- %indvars.iv428 = phi i64 [ 0, %for.body86.preheader.new ], [ %indvars.iv.next429.3, %for.body86 ]
- %niter518 = phi i64 [ 0, %for.body86.preheader.new ], [ %niter518.next.3, %for.body86 ]
- %indvars433 = trunc i64 %indvars.iv428 to i32
- %mul87 = mul nuw nsw i32 %indvars433, %indvars433
- %mul88327 = or disjoint i32 %mul87, 1
- %mul89326 = mul i32 %mul88327, %indvars433
- %add91328 = or disjoint i32 %mul89326, 3
- %add93 = mul i32 %add91328, %indvars433
- %arrayidx95 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv428
- store i32 %add93, ptr %arrayidx95, align 8, !tbaa !4
- %indvars.iv.next429 = or disjoint i64 %indvars.iv428, 1
- %indvars433.1 = trunc i64 %indvars.iv.next429 to i32
- %mul87.1 = mul nuw nsw i32 %indvars433.1, %indvars433.1
- %mul88327.1 = add nuw nsw i32 %mul87.1, 1
- %mul89326.1 = mul i32 %mul88327.1, %indvars433.1
- %add91328.1 = add i32 %mul89326.1, 3
- %add93.1 = mul i32 %add91328.1, %indvars433.1
- %arrayidx95.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429
- store i32 %add93.1, ptr %arrayidx95.1, align 4, !tbaa !4
- %indvars.iv.next429.1 = or disjoint i64 %indvars.iv428, 2
- %indvars433.2 = trunc i64 %indvars.iv.next429.1 to i32
- %mul87.2 = mul nuw nsw i32 %indvars433.2, %indvars433.2
- %mul88327.2 = or disjoint i32 %mul87.2, 1
- %mul89326.2 = mul i32 %mul88327.2, %indvars433.2
- %add91328.2 = add i32 %mul89326.2, 3
- %add93.2 = mul i32 %add91328.2, %indvars433.2
- %arrayidx95.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429.1
- store i32 %add93.2, ptr %arrayidx95.2, align 8, !tbaa !4
- %indvars.iv.next429.2 = or disjoint i64 %indvars.iv428, 3
- %indvars433.3 = trunc i64 %indvars.iv.next429.2 to i32
- %mul87.3 = mul nuw nsw i32 %indvars433.3, %indvars433.3
- %mul88327.3 = add nuw nsw i32 %mul87.3, 1
- %mul89326.3 = mul i32 %mul88327.3, %indvars433.3
- %add91328.3 = add i32 %mul89326.3, 3
- %add93.3 = mul i32 %add91328.3, %indvars433.3
- %arrayidx95.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429.2
- store i32 %add93.3, ptr %arrayidx95.3, align 4, !tbaa !4
- %indvars.iv.next429.3 = add nuw nsw i64 %indvars.iv428, 4
- %niter518.next.3 = add i64 %niter518, 4
- %niter518.ncmp.3 = icmp eq i64 %niter518.next.3, %unroll_iter517
- br i1 %niter518.ncmp.3, label %sw.epilog.loopexit483.unr-lcssa, label %for.body86, !llvm.loop !16
-
-sw.epilog.loopexit.unr-lcssa: ; preds = %for.body17, %for.body17.preheader
- %indvars.iv455.unr = phi i64 [ 0, %for.body17.preheader ], [ %indvars.iv.next456.3, %for.body17 ]
- %lcmp.mod536.not = icmp eq i64 %xtraiter534, 0
- br i1 %lcmp.mod536.not, label %sw.epilog, label %for.body17.epil
-
-for.body17.epil: ; preds = %sw.epilog.loopexit.unr-lcssa, %for.body17.epil
- %indvars.iv455.epil = phi i64 [ %indvars.iv.next456.epil, %for.body17.epil ], [ %indvars.iv455.unr, %sw.epilog.loopexit.unr-lcssa ]
- %epil.iter535 = phi i64 [ %epil.iter535.next, %for.body17.epil ], [ 0, %sw.epilog.loopexit.unr-lcssa ]
- %indvars459.epil = trunc i64 %indvars.iv455.epil to i32
- %mul19340.epil = add nuw i32 %indvars459.epil, 3
- %add20.epil = mul i32 %mul19340.epil, %indvars459.epil
- %arrayidx22.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv455.epil
- store i32 %add20.epil, ptr %arrayidx22.epil, align 4, !tbaa !4
- %indvars.iv.next456.epil = add nuw nsw i64 %indvars.iv455.epil, 1
- %epil.iter535.next = add i64 %epil.iter535, 1
- %epil.iter535.cmp.not = icmp eq i64 %epil.iter535.next, %xtraiter534
- br i1 %epil.iter535.cmp.not, label %sw.epilog, label %for.body17.epil, !llvm.loop !17
-
-sw.epilog.loopexit480.unr-lcssa: ; preds = %for.body33, %for.body33.preheader
- %indvars.iv449.unr = phi i64 [ 0, %for.body33.preheader ], [ %indvars.iv.next450.3, %for.body33 ]
- %lcmp.mod531.not = icmp eq i64 %xtraiter529, 0
- br i1 %lcmp.mod531.not, label %sw.epilog, label %for.body33.epil
-
-for.body33.epil: ; preds = %sw.epilog.loopexit480.unr-lcssa, %for.body33.epil
- %indvars.iv449.epil = phi i64 [ %indvars.iv.next450.epil, %for.body33.epil ], [ %indvars.iv449.unr, %sw.epilog.loopexit480.unr-lcssa ]
- %epil.iter530 = phi i64 [ %epil.iter530.next, %for.body33.epil ], [ 0, %sw.epilog.loopexit480.unr-lcssa ]
- %indvars.iv.next450.epil = add nuw nsw i64 %indvars.iv449.epil, 1
- %indvars451.epil = trunc i64 %indvars.iv.next450.epil to i32
- %29 = trunc nuw nsw i64 %indvars.iv449.epil to i32
- %mul35336.epil = mul i32 %indvars451.epil, %29
- %add37338.epil = add i32 %mul35336.epil, 3
- %add39.epil = mul i32 %add37338.epil, %29
- %arrayidx41.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv449.epil
- store i32 %add39.epil, ptr %arrayidx41.epil, align 4, !tbaa !4
- %epil.iter530.next = add i64 %epil.iter530, 1
- %epil.iter530.cmp.not = icmp eq i64 %epil.iter530.next, %xtraiter529
- br i1 %epil.iter530.cmp.not, label %sw.epilog, label %for.body33.epil, !llvm.loop !18
-
-sw.epilog.loopexit481.unr-lcssa: ; preds = %for.body52, %for.body52.preheader
- %indvars.iv442.unr = phi i64 [ 0, %for.body52.preheader ], [ %indvars.iv.next443.3, %for.body52 ]
- %lcmp.mod526.not = icmp eq i64 %xtraiter524, 0
- br i1 %lcmp.mod526.not, label %sw.epilog, label %for.body52.epil
-
-for.body52.epil: ; preds = %sw.epilog.loopexit481.unr-lcssa, %for.body52.epil
- %indvars.iv442.epil = phi i64 [ %indvars.iv.next443.epil, %for.body52.epil ], [ %indvars.iv442.unr, %sw.epilog.loopexit481.unr-lcssa ]
- %epil.iter525 = phi i64 [ %epil.iter525.next, %for.body52.epil ], [ 0, %sw.epilog.loopexit481.unr-lcssa ]
- %indvars446.epil = trunc i64 %indvars.iv442.epil to i32
- %i47.0333.epil = add nsw i32 %indvars446.epil, -1
- %mul54332.epil = mul i32 %i47.0333.epil, %indvars446.epil
- %sub334.epil = add i32 %mul54332.epil, 3
- %add57.epil = mul i32 %sub334.epil, %indvars446.epil
- %arrayidx59.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv442.epil
- store i32 %add57.epil, ptr %arrayidx59.epil, align 4, !tbaa !4
- %indvars.iv.next443.epil = add nuw nsw i64 %indvars.iv442.epil, 1
- %epil.iter525.next = add i64 %epil.iter525, 1
- %epil.iter525.cmp.not = icmp eq i64 %epil.iter525.next, %xtraiter524
- br i1 %epil.iter525.cmp.not, label %sw.epilog, label %for.body52.epil, !llvm.loop !19
-
-sw.epilog.loopexit482.unr-lcssa: ; preds = %for.body70, %for.body70.preheader
- %indvars.iv436.unr = phi i64 [ 0, %for.body70.preheader ], [ %indvars.iv.next437.3, %for.body70 ]
- %lcmp.mod521.not = icmp eq i64 %xtraiter519, 0
- br i1 %lcmp.mod521.not, label %sw.epilog, label %for.body70.epil
-
-for.body70.epil: ; preds = %sw.epilog.loopexit482.unr-lcssa, %for.body70.epil
- %indvars.iv436.epil = phi i64 [ %indvars.iv.next437.epil, %for.body70.epil ], [ %indvars.iv436.unr, %sw.epilog.loopexit482.unr-lcssa ]
- %epil.iter520 = phi i64 [ %epil.iter520.next, %for.body70.epil ], [ 0, %sw.epilog.loopexit482.unr-lcssa ]
- %indvars.iv.next437.epil = add nuw nsw i64 %indvars.iv436.epil, 1
- %indvars438.epil = trunc i64 %indvars.iv.next437.epil to i32
- %30 = trunc nuw nsw i64 %indvars.iv436.epil to i32
- %add72.epil = mul i32 %indvars438.epil, %30
- %add73.epil = add nsw i32 %add72.epil, 3
- %arrayidx75.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv436.epil
- store i32 %add73.epil, ptr %arrayidx75.epil, align 4, !tbaa !4
- %epil.iter520.next = add i64 %epil.iter520, 1
- %epil.iter520.cmp.not = icmp eq i64 %epil.iter520.next, %xtraiter519
- br i1 %epil.iter520.cmp.not, label %sw.epilog, label %for.body70.epil, !llvm.loop !20
-
-sw.epilog.loopexit483.unr-lcssa: ; preds = %for.body86, %for.body86.preheader
- %indvars.iv428.unr = phi i64 [ 0, %for.body86.preheader ], [ %indvars.iv.next429.3, %for.body86 ]
- %lcmp.mod516.not = icmp eq i64 %xtraiter514, 0
- br i1 %lcmp.mod516.not, label %sw.epilog, label %for.body86.epil
-
-for.body86.epil: ; preds = %sw.epilog.loopexit483.unr-lcssa, %for.body86.epil
- %indvars.iv428.epil = phi i64 [ %indvars.iv.next429.epil, %for.body86.epil ], [ %indvars.iv428.unr, %sw.epilog.loopexit483.unr-lcssa ]
- %epil.iter515 = phi i64 [ %epil.iter515.next, %for.body86.epil ], [ 0, %sw.epilog.loopexit483.unr-lcssa ]
- %indvars433.epil = trunc i64 %indvars.iv428.epil to i32
- %mul87.epil = mul nuw nsw i32 %indvars433.epil, %indvars433.epil
- %mul88327.epil = add nuw i32 %mul87.epil, 1
- %mul89326.epil = mul i32 %mul88327.epil, %indvars433.epil
- %add91328.epil = add i32 %mul89326.epil, 3
- %add93.epil = mul i32 %add91328.epil, %indvars433.epil
- %arrayidx95.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv428.epil
- store i32 %add93.epil, ptr %arrayidx95.epil, align 4, !tbaa !4
- %indvars.iv.next429.epil = add nuw nsw i64 %indvars.iv428.epil, 1
- %epil.iter515.next = add i64 %epil.iter515, 1
- %epil.iter515.cmp.not = icmp eq i64 %epil.iter515.next, %xtraiter514
- br i1 %epil.iter515.cmp.not, label %sw.epilog, label %for.body86.epil, !llvm.loop !21
-
-sw.epilog: ; preds = %sw.epilog.loopexit483.unr-lcssa, %for.body86.epil, %sw.epilog.loopexit482.unr-lcssa, %for.body70.epil, %sw.epilog.loopexit481.unr-lcssa, %for.body52.epil, %sw.epilog.loopexit480.unr-lcssa, %for.body33.epil, %sw.epilog.loopexit.unr-lcssa, %for.body17.epil, %sw.bb79, %sw.bb63, %sw.bb45, %sw.bb26, %sw.bb, %if.then9
- call void @func4()
+ br i1 %28, label %sw.epilog.loopexit481.unr-lcssa, label %for.body84.preheader.new
+
+for.body84.preheader.new: ; preds = %for.body84.preheader
+ %unroll_iter515 = and i64 %wide.trip.count432, 2147483644
+ br label %for.body84
+
+for.body84: ; preds = %for.body84, %for.body84.preheader.new
+ %indvars.iv426 = phi i64 [ 0, %for.body84.preheader.new ], [ %indvars.iv.next427.3, %for.body84 ]
+ %niter516 = phi i64 [ 0, %for.body84.preheader.new ], [ %niter516.next.3, %for.body84 ]
+ %indvars431 = trunc i64 %indvars.iv426 to i32
+ %mul85 = mul nuw nsw i32 %indvars431, %indvars431
+ %mul86325 = or disjoint i32 %mul85, 1
+ %mul87324 = mul i32 %mul86325, %indvars431
+ %add89326 = or disjoint i32 %mul87324, 3
+ %add91 = mul i32 %add89326, %indvars431
+ %arrayidx93 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv426
+ store i32 %add91, ptr %arrayidx93, align 8, !tbaa !4
+ %indvars.iv.next427 = or disjoint i64 %indvars.iv426, 1
+ %indvars431.1 = trunc i64 %indvars.iv.next427 to i32
+ %mul85.1 = mul nuw nsw i32 %indvars431.1, %indvars431.1
+ %mul86325.1 = add nuw nsw i32 %mul85.1, 1
+ %mul87324.1 = mul i32 %mul86325.1, %indvars431.1
+ %add89326.1 = add i32 %mul87324.1, 3
+ %add91.1 = mul i32 %add89326.1, %indvars431.1
+ %arrayidx93.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next427
+ store i32 %add91.1, ptr %arrayidx93.1, align 4, !tbaa !4
+ %indvars.iv.next427.1 = or disjoint i64 %indvars.iv426, 2
+ %indvars431.2 = trunc i64 %indvars.iv.next427.1 to i32
+ %mul85.2 = mul nuw nsw i32 %indvars431.2, %indvars431.2
+ %mul86325.2 = or disjoint i32 %mul85.2, 1
+ %mul87324.2 = mul i32 %mul86325.2, %indvars431.2
+ %add89326.2 = add i32 %mul87324.2, 3
+ %add91.2 = mul i32 %add89326.2, %indvars431.2
+ %arrayidx93.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next427.1
+ store i32 %add91.2, ptr %arrayidx93.2, align 8, !tbaa !4
+ %indvars.iv.next427.2 = or disjoint i64 %indvars.iv426, 3
+ %indvars431.3 = trunc i64 %indvars.iv.next427.2 to i32
+ %mul85.3 = mul nuw nsw i32 %indvars431.3, %indvars431.3
+ %mul86325.3 = add nuw nsw i32 %mul85.3, 1
+ %mul87324.3 = mul i32 %mul86325.3, %indvars431.3
+ %add89326.3 = add i32 %mul87324.3, 3
+ %add91.3 = mul i32 %add89326.3, %indvars431.3
+ %arrayidx93.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next427.2
+ store i32 %add91.3, ptr %arrayidx93.3, align 4, !tbaa !4
+ %indvars.iv.next427.3 = add nuw nsw i64 %indvars.iv426, 4
+ %niter516.next.3 = add i64 %niter516, 4
+ %niter516.ncmp.3 = icmp eq i64 %niter516.next.3, %unroll_iter515
+ br i1 %niter516.ncmp.3, label %sw.epilog.loopexit481.unr-lcssa, label %for.body84, !llvm.loop !16
+
+sw.epilog.loopexit.unr-lcssa: ; preds = %for.body15, %for.body15.preheader
+ %indvars.iv453.unr = phi i64 [ 0, %for.body15.preheader ], [ %indvars.iv.next454.3, %for.body15 ]
+ %lcmp.mod534.not = icmp eq i64 %xtraiter532, 0
+ br i1 %lcmp.mod534.not, label %sw.epilog, label %for.body15.epil
+
+for.body15.epil: ; preds = %sw.epilog.loopexit.unr-lcssa, %for.body15.epil
+ %indvars.iv453.epil = phi i64 [ %indvars.iv.next454.epil, %for.body15.epil ], [ %indvars.iv453.unr, %sw.epilog.loopexit.unr-lcssa ]
+ %epil.iter533 = phi i64 [ %epil.iter533.next, %for.body15.epil ], [ 0, %sw.epilog.loopexit.unr-lcssa ]
+ %indvars457.epil = trunc i64 %indvars.iv453.epil to i32
+ %mul17338.epil = add nuw i32 %indvars457.epil, 3
+ %add18.epil = mul i32 %mul17338.epil, %indvars457.epil
+ %arrayidx20.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv453.epil
+ store i32 %add18.epil, ptr %arrayidx20.epil, align 4, !tbaa !4
+ %indvars.iv.next454.epil = add nuw nsw i64 %indvars.iv453.epil, 1
+ %epil.iter533.next = add i64 %epil.iter533, 1
+ %epil.iter533.cmp.not = icmp eq i64 %epil.iter533.next, %xtraiter532
+ br i1 %epil.iter533.cmp.not, label %sw.epilog, label %for.body15.epil, !llvm.loop !17
+
+sw.epilog.loopexit478.unr-lcssa: ; preds = %for.body31, %for.body31.preheader
+ %indvars.iv447.unr = phi i64 [ 0, %for.body31.preheader ], [ %indvars.iv.next448.3, %for.body31 ]
+ %lcmp.mod529.not = icmp eq i64 %xtraiter527, 0
+ br i1 %lcmp.mod529.not, label %sw.epilog, label %for.body31.epil
+
+for.body31.epil: ; preds = %sw.epilog.loopexit478.unr-lcssa, %for.body31.epil
+ %indvars.iv447.epil = phi i64 [ %indvars.iv.next448.epil, %for.body31.epil ], [ %indvars.iv447.unr, %sw.epilog.loopexit478.unr-lcssa ]
+ %epil.iter528 = phi i64 [ %epil.iter528.next, %for.body31.epil ], [ 0, %sw.epilog.loopexit478.unr-lcssa ]
+ %indvars.iv.next448.epil = add nuw nsw i64 %indvars.iv447.epil, 1
+ %indvars449.epil = trunc i64 %indvars.iv.next448.epil to i32
+ %29 = trunc nuw nsw i64 %indvars.iv447.epil to i32
+ %mul33334.epil = mul i32 %indvars449.epil, %29
+ %add35336.epil = add i32 %mul33334.epil, 3
+ %add37.epil = mul i32 %add35336.epil, %29
+ %arrayidx39.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv447.epil
+ store i32 %add37.epil, ptr %arrayidx39.epil, align 4, !tbaa !4
+ %epil.iter528.next = add i64 %epil.iter528, 1
+ %epil.iter528.cmp.not = icmp eq i64 %epil.iter528.next, %xtraiter527
+ br i1 %epil.iter528.cmp.not, label %sw.epilog, label %for.body31.epil, !llvm.loop !18
+
+sw.epilog.loopexit479.unr-lcssa: ; preds = %for.body50, %for.body50.preheader
+ %indvars.iv440.unr = phi i64 [ 0, %for.body50.preheader ], [ %indvars.iv.next441.3, %for.body50 ]
+ %lcmp.mod524.not = icmp eq i64 %xtraiter522, 0
+ br i1 %lcmp.mod524.not, label %sw.epilog, label %for.body50.epil
+
+for.body50.epil: ; preds = %sw.epilog.loopexit479.unr-lcssa, %for.body50.epil
+ %indvars.iv440.epil = phi i64 [ %indvars.iv.next441.epil, %for.body50.epil ], [ %indvars.iv440.unr, %sw.epilog.loopexit479.unr-lcssa ]
+ %epil.iter523 = phi i64 [ %epil.iter523.next, %for.body50.epil ], [ 0, %sw.epilog.loopexit479.unr-lcssa ]
+ %indvars444.epil = trunc i64 %indvars.iv440.epil to i32
+ %i45.0331.epil = add nsw i32 %indvars444.epil, -1
+ %mul52330.epil = mul i32 %i45.0331.epil, %indvars444.epil
+ %sub332.epil = add i32 %mul52330.epil, 3
+ %add55.epil = mul i32 %sub332.epil, %indvars444.epil
+ %arrayidx57.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv440.epil
+ store i32 %add55.epil, ptr %arrayidx57.epil, align 4, !tbaa !4
+ %indvars.iv.next441.epil = add nuw nsw i64 %indvars.iv440.epil, 1
+ %epil.iter523.next = add i64 %epil.iter523, 1
+ %epil.iter523.cmp.not = icmp eq i64 %epil.iter523.next, %xtraiter522
+ br i1 %epil.iter523.cmp.not, label %sw.epilog, label %for.body50.epil, !llvm.loop !19
+
+sw.epilog.loopexit480.unr-lcssa: ; preds = %for.body68, %for.body68.preheader
+ %indvars.iv434.unr = phi i64 [ 0, %for.body68.preheader ], [ %indvars.iv.next435.3, %for.body68 ]
+ %lcmp.mod519.not = icmp eq i64 %xtraiter517, 0
+ br i1 %lcmp.mod519.not, label %sw.epilog, label %for.body68.epil
+
+for.body68.epil: ; preds = %sw.epilog.loopexit480.unr-lcssa, %for.body68.epil
+ %indvars.iv434.epil = phi i64 [ %indvars.iv.next435.epil, %for.body68.epil ], [ %indvars.iv434.unr, %sw.epilog.loopexit480.unr-lcssa ]
+ %epil.iter518 = phi i64 [ %epil.iter518.next, %for.body68.epil ], [ 0, %sw.epilog.loopexit480.unr-lcssa ]
+ %indvars.iv.next435.epil = add nuw nsw i64 %indvars.iv434.epil, 1
+ %indvars436.epil = trunc i64 %indvars.iv.next435.epil to i32
+ %30 = trunc nuw nsw i64 %indvars.iv434.epil to i32
+ %add70.epil = mul i32 %indvars436.epil, %30
+ %add71.epil = add nsw i32 %add70.epil, 3
+ %arrayidx73.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv434.epil
+ store i32 %add71.epil, ptr %arrayidx73.epil, align 4, !tbaa !4
+ %epil.iter518.next = add i64 %epil.iter518, 1
+ %epil.iter518.cmp.not = icmp eq i64 %epil.iter518.next, %xtraiter517
+ br i1 %epil.iter518.cmp.not, label %sw.epilog, label %for.body68.epil, !llvm.loop !20
+
+sw.epilog.loopexit481.unr-lcssa: ; preds = %for.body84, %for.body84.preheader
+ %indvars.iv426.unr = phi i64 [ 0, %for.body84.preheader ], [ %indvars.iv.next427.3, %for.body84 ]
+ %lcmp.mod514.not = icmp eq i64 %xtraiter512, 0
+ br i1 %lcmp.mod514.not, label %sw.epilog, label %for.body84.epil
+
+for.body84.epil: ; preds = %sw.epilog.loopexit481.unr-lcssa, %for.body84.epil
+ %indvars.iv426.epil = phi i64 [ %indvars.iv.next427.epil, %for.body84.epil ], [ %indvars.iv426.unr, %sw.epilog.loopexit481.unr-lcssa ]
+ %epil.iter513 = phi i64 [ %epil.iter513.next, %for.body84.epil ], [ 0, %sw.epilog.loopexit481.unr-lcssa ]
+ %indvars431.epil = trunc i64 %indvars.iv426.epil to i32
+ %mul85.epil = mul nuw nsw i32 %indvars431.epil, %indvars431.epil
+ %mul86325.epil = add nuw i32 %mul85.epil, 1
+ %mul87324.epil = mul i32 %mul86325.epil, %indvars431.epil
+ %add89326.epil = add i32 %mul87324.epil, 3
+ %add91.epil = mul i32 %add89326.epil, %indvars431.epil
+ %arrayidx93.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv426.epil
+ store i32 %add91.epil, ptr %arrayidx93.epil, align 4, !tbaa !4
+ %indvars.iv.next427.epil = add nuw nsw i64 %indvars.iv426.epil, 1
+ %epil.iter513.next = add i64 %epil.iter513, 1
+ %epil.iter513.cmp.not = icmp eq i64 %epil.iter513.next, %xtraiter512
+ br i1 %epil.iter513.cmp.not, label %sw.epilog, label %for.body84.epil, !llvm.loop !21
+
+sw.epilog: ; preds = %sw.epilog.loopexit481.unr-lcssa, %for.body84.epil, %sw.epilog.loopexit480.unr-lcssa, %for.body68.epil, %sw.epilog.loopexit479.unr-lcssa, %for.body50.epil, %sw.epilog.loopexit478.unr-lcssa, %for.body31.epil, %sw.epilog.loopexit.unr-lcssa, %for.body15.epil, %sw.bb77, %sw.bb61, %sw.bb43, %sw.bb24, %sw.bb, %if.then7
+ tail call void @func4()
unreachable
if.else: ; preds = %if.then
- %puts308 = call i32 @puts(ptr nonnull dereferenceable(1) @str.21)
- %31 = load i32, ptr %len, align 4, !tbaa !4
- %cmp102354 = icmp sgt i32 %31, 0
- br i1 %cmp102354, label %for.body105, label %for.cond.cleanup104
-
-for.cond.cleanup104: ; preds = %for.body105, %if.else
- %.lcssa = phi i32 [ %31, %if.else ], [ %33, %for.body105 ]
- %rem112 = srem i32 %.lcssa, 5
- switch i32 %rem112, label %sw.epilog201 [
- i32 0, label %sw.bb113
- i32 1, label %sw.bb133
- i32 2, label %sw.bb149
- i32 3, label %sw.bb166
- i32 4, label %sw.bb185
+ %puts306 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %31 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp100352 = icmp sgt i32 %31, 0
+ br i1 %cmp100352, label %for.body103, label %for.cond.cleanup102
+
+for.cond.cleanup102: ; preds = %for.body103, %if.else
+ %.lcssa = phi i32 [ %31, %if.else ], [ %33, %for.body103 ]
+ %rem110 = srem i32 %.lcssa, 5
+ switch i32 %rem110, label %sw.epilog199 [
+ i32 0, label %sw.bb111
+ i32 1, label %sw.bb131
+ i32 2, label %sw.bb147
+ i32 3, label %sw.bb164
+ i32 4, label %sw.bb183
]
-for.body105: ; preds = %if.else, %for.body105
- %indvars.iv390 = phi i64 [ %indvars.iv.next391, %for.body105 ], [ 0, %if.else ]
- %arrayidx107 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv390
- %32 = load i32, ptr %arrayidx107, align 4, !tbaa !4
- %call108 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %32)
- %indvars.iv.next391 = add nuw nsw i64 %indvars.iv390, 1
- %33 = load i32, ptr %len, align 4, !tbaa !4
+for.body103: ; preds = %if.else, %for.body103
+ %indvars.iv388 = phi i64 [ %indvars.iv.next389, %for.body103 ], [ 0, %if.else ]
+ %arrayidx105 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv388
+ %32 = load i32, ptr %arrayidx105, align 4, !tbaa !4
+ %call106 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %32)
+ %indvars.iv.next389 = add nuw nsw i64 %indvars.iv388, 1
+ %33 = load i32, ptr @len, align 4, !tbaa !4
%34 = sext i32 %33 to i64
- %cmp102 = icmp slt i64 %indvars.iv.next391, %34
- br i1 %cmp102, label %for.body105, label %for.cond.cleanup104, !llvm.loop !22
-
-sw.bb113: ; preds = %for.cond.cleanup104
- %puts320 = call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
- %35 = load i32, ptr %len, align 4, !tbaa !4
- %cmp117364 = icmp sgt i32 %35, 0
- br i1 %cmp117364, label %for.body120.preheader, label %sw.epilog201
-
-for.body120.preheader: ; preds = %sw.bb113
- %wide.trip.count426 = zext nneg i32 %35 to i64
- %xtraiter509 = and i64 %wide.trip.count426, 3
+ %cmp100 = icmp slt i64 %indvars.iv.next389, %34
+ br i1 %cmp100, label %for.body103, label %for.cond.cleanup102, !llvm.loop !22
+
+sw.bb111: ; preds = %for.cond.cleanup102
+ %puts318 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
+ %35 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp115362 = icmp sgt i32 %35, 0
+ br i1 %cmp115362, label %for.body118.preheader, label %sw.epilog199
+
+for.body118.preheader: ; preds = %sw.bb111
+ %wide.trip.count424 = zext nneg i32 %35 to i64
+ %xtraiter507 = and i64 %wide.trip.count424, 3
%36 = icmp ult i32 %35, 4
- br i1 %36, label %sw.epilog201.loopexit.unr-lcssa, label %for.body120.preheader.new
-
-for.body120.preheader.new: ; preds = %for.body120.preheader
- %unroll_iter512 = and i64 %wide.trip.count426, 2147483644
- br label %for.body120
-
-for.body120: ; preds = %for.body120, %for.body120.preheader.new
- %indvars.iv420 = phi i64 [ 0, %for.body120.preheader.new ], [ %indvars.iv.next421.3, %for.body120 ]
- %niter513 = phi i64 [ 0, %for.body120.preheader.new ], [ %niter513.next.3, %for.body120 ]
- %indvars425 = trunc i64 %indvars.iv420 to i32
- %mul121 = mul nuw nsw i32 %indvars425, %indvars425
- %mul122322 = or disjoint i32 %mul121, 1
- %mul123321 = mul i32 %mul122322, %indvars425
- %add125323 = or disjoint i32 %mul123321, 3
- %add127 = mul i32 %add125323, %indvars425
- %arrayidx129 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv420
- store i32 %add127, ptr %arrayidx129, align 8, !tbaa !4
- %indvars.iv.next421 = or disjoint i64 %indvars.iv420, 1
- %indvars425.1 = trunc i64 %indvars.iv.next421 to i32
- %mul121.1 = mul nuw nsw i32 %indvars425.1, %indvars425.1
- %mul122322.1 = add nuw nsw i32 %mul121.1, 1
- %mul123321.1 = mul i32 %mul122322.1, %indvars425.1
- %add125323.1 = add i32 %mul123321.1, 3
- %add127.1 = mul i32 %add125323.1, %indvars425.1
- %arrayidx129.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421
- store i32 %add127.1, ptr %arrayidx129.1, align 4, !tbaa !4
- %indvars.iv.next421.1 = or disjoint i64 %indvars.iv420, 2
- %indvars425.2 = trunc i64 %indvars.iv.next421.1 to i32
- %mul121.2 = mul nuw nsw i32 %indvars425.2, %indvars425.2
- %mul122322.2 = or disjoint i32 %mul121.2, 1
- %mul123321.2 = mul i32 %mul122322.2, %indvars425.2
- %add125323.2 = add i32 %mul123321.2, 3
- %add127.2 = mul i32 %add125323.2, %indvars425.2
- %arrayidx129.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421.1
- store i32 %add127.2, ptr %arrayidx129.2, align 8, !tbaa !4
- %indvars.iv.next421.2 = or disjoint i64 %indvars.iv420, 3
- %indvars425.3 = trunc i64 %indvars.iv.next421.2 to i32
- %mul121.3 = mul nuw nsw i32 %indvars425.3, %indvars425.3
- %mul122322.3 = add nuw nsw i32 %mul121.3, 1
- %mul123321.3 = mul i32 %mul122322.3, %indvars425.3
- %add125323.3 = add i32 %mul123321.3, 3
- %add127.3 = mul i32 %add125323.3, %indvars425.3
- %arrayidx129.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421.2
- store i32 %add127.3, ptr %arrayidx129.3, align 4, !tbaa !4
- %indvars.iv.next421.3 = add nuw nsw i64 %indvars.iv420, 4
- %niter513.next.3 = add i64 %niter513, 4
- %niter513.ncmp.3 = icmp eq i64 %niter513.next.3, %unroll_iter512
- br i1 %niter513.ncmp.3, label %sw.epilog201.loopexit.unr-lcssa, label %for.body120, !llvm.loop !23
-
-sw.bb133: ; preds = %for.cond.cleanup104
- %puts318 = call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
- %37 = load i32, ptr %len, align 4, !tbaa !4
- %cmp137362 = icmp sgt i32 %37, 0
- br i1 %cmp137362, label %for.body140.preheader, label %sw.epilog201
-
-for.body140.preheader: ; preds = %sw.bb133
- %wide.trip.count418 = zext nneg i32 %37 to i64
- %xtraiter504 = and i64 %wide.trip.count418, 3
+ br i1 %36, label %sw.epilog199.loopexit.unr-lcssa, label %for.body118.preheader.new
+
+for.body118.preheader.new: ; preds = %for.body118.preheader
+ %unroll_iter510 = and i64 %wide.trip.count424, 2147483644
+ br label %for.body118
+
+for.body118: ; preds = %for.body118, %for.body118.preheader.new
+ %indvars.iv418 = phi i64 [ 0, %for.body118.preheader.new ], [ %indvars.iv.next419.3, %for.body118 ]
+ %niter511 = phi i64 [ 0, %for.body118.preheader.new ], [ %niter511.next.3, %for.body118 ]
+ %indvars423 = trunc i64 %indvars.iv418 to i32
+ %mul119 = mul nuw nsw i32 %indvars423, %indvars423
+ %mul120320 = or disjoint i32 %mul119, 1
+ %mul121319 = mul i32 %mul120320, %indvars423
+ %add123321 = or disjoint i32 %mul121319, 3
+ %add125 = mul i32 %add123321, %indvars423
+ %arrayidx127 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv418
+ store i32 %add125, ptr %arrayidx127, align 8, !tbaa !4
+ %indvars.iv.next419 = or disjoint i64 %indvars.iv418, 1
+ %indvars423.1 = trunc i64 %indvars.iv.next419 to i32
+ %mul119.1 = mul nuw nsw i32 %indvars423.1, %indvars423.1
+ %mul120320.1 = add nuw nsw i32 %mul119.1, 1
+ %mul121319.1 = mul i32 %mul120320.1, %indvars423.1
+ %add123321.1 = add i32 %mul121319.1, 3
+ %add125.1 = mul i32 %add123321.1, %indvars423.1
+ %arrayidx127.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next419
+ store i32 %add125.1, ptr %arrayidx127.1, align 4, !tbaa !4
+ %indvars.iv.next419.1 = or disjoint i64 %indvars.iv418, 2
+ %indvars423.2 = trunc i64 %indvars.iv.next419.1 to i32
+ %mul119.2 = mul nuw nsw i32 %indvars423.2, %indvars423.2
+ %mul120320.2 = or disjoint i32 %mul119.2, 1
+ %mul121319.2 = mul i32 %mul120320.2, %indvars423.2
+ %add123321.2 = add i32 %mul121319.2, 3
+ %add125.2 = mul i32 %add123321.2, %indvars423.2
+ %arrayidx127.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next419.1
+ store i32 %add125.2, ptr %arrayidx127.2, align 8, !tbaa !4
+ %indvars.iv.next419.2 = or disjoint i64 %indvars.iv418, 3
+ %indvars423.3 = trunc i64 %indvars.iv.next419.2 to i32
+ %mul119.3 = mul nuw nsw i32 %indvars423.3, %indvars423.3
+ %mul120320.3 = add nuw nsw i32 %mul119.3, 1
+ %mul121319.3 = mul i32 %mul120320.3, %indvars423.3
+ %add123321.3 = add i32 %mul121319.3, 3
+ %add125.3 = mul i32 %add123321.3, %indvars423.3
+ %arrayidx127.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next419.2
+ store i32 %add125.3, ptr %arrayidx127.3, align 4, !tbaa !4
+ %indvars.iv.next419.3 = add nuw nsw i64 %indvars.iv418, 4
+ %niter511.next.3 = add i64 %niter511, 4
+ %niter511.ncmp.3 = icmp eq i64 %niter511.next.3, %unroll_iter510
+ br i1 %niter511.ncmp.3, label %sw.epilog199.loopexit.unr-lcssa, label %for.body118, !llvm.loop !23
+
+sw.bb131: ; preds = %for.cond.cleanup102
+ %puts316 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
+ %37 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp135360 = icmp sgt i32 %37, 0
+ br i1 %cmp135360, label %for.body138.preheader, label %sw.epilog199
+
+for.body138.preheader: ; preds = %sw.bb131
+ %wide.trip.count416 = zext nneg i32 %37 to i64
+ %xtraiter502 = and i64 %wide.trip.count416, 3
%38 = icmp ult i32 %37, 4
- br i1 %38, label %sw.epilog201.loopexit484.unr-lcssa, label %for.body140.preheader.new
-
-for.body140.preheader.new: ; preds = %for.body140.preheader
- %unroll_iter507 = and i64 %wide.trip.count418, 2147483644
- br label %for.body140
-
-for.body140: ; preds = %for.body140, %for.body140.preheader.new
- %indvars.iv414 = phi i64 [ 0, %for.body140.preheader.new ], [ %indvars.iv.next415.3, %for.body140 ]
- %niter508 = phi i64 [ 0, %for.body140.preheader.new ], [ %niter508.next.3, %for.body140 ]
- %indvars.iv.next415 = or disjoint i64 %indvars.iv414, 1
- %indvars416 = trunc i64 %indvars.iv.next415 to i32
- %39 = trunc nuw nsw i64 %indvars.iv414 to i32
- %add142 = mul i32 %indvars416, %39
- %add143 = or disjoint i32 %add142, 3
- %arrayidx145 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv414
- store i32 %add143, ptr %arrayidx145, align 8, !tbaa !4
- %indvars.iv.next415.1 = or disjoint i64 %indvars.iv414, 2
- %indvars416.1 = trunc i64 %indvars.iv.next415.1 to i32
- %40 = trunc nuw nsw i64 %indvars.iv.next415 to i32
- %add142.1 = mul i32 %indvars416.1, %40
- %add143.1 = add nsw i32 %add142.1, 3
- %arrayidx145.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415
- store i32 %add143.1, ptr %arrayidx145.1, align 4, !tbaa !4
- %indvars.iv.next415.2 = or disjoint i64 %indvars.iv414, 3
- %indvars416.2 = trunc i64 %indvars.iv.next415.2 to i32
- %41 = trunc nuw nsw i64 %indvars.iv.next415.1 to i32
- %add142.2 = mul i32 %indvars416.2, %41
- %add143.2 = add nsw i32 %add142.2, 3
- %arrayidx145.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415.1
- store i32 %add143.2, ptr %arrayidx145.2, align 8, !tbaa !4
- %indvars.iv.next415.3 = add nuw nsw i64 %indvars.iv414, 4
- %indvars416.3 = trunc i64 %indvars.iv.next415.3 to i32
- %42 = trunc nuw nsw i64 %indvars.iv.next415.2 to i32
- %add142.3 = mul i32 %indvars416.3, %42
- %add143.3 = or disjoint i32 %add142.3, 3
- %arrayidx145.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415.2
- store i32 %add143.3, ptr %arrayidx145.3, align 4, !tbaa !4
- %niter508.next.3 = add i64 %niter508, 4
- %niter508.ncmp.3 = icmp eq i64 %niter508.next.3, %unroll_iter507
- br i1 %niter508.ncmp.3, label %sw.epilog201.loopexit484.unr-lcssa, label %for.body140, !llvm.loop !24
-
-sw.bb149: ; preds = %for.cond.cleanup104
- %puts315 = call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
- %43 = load i32, ptr %len, align 4, !tbaa !4
- %cmp153360 = icmp sgt i32 %43, 0
- br i1 %cmp153360, label %for.body156.preheader, label %sw.epilog201
-
-for.body156.preheader: ; preds = %sw.bb149
- %wide.trip.count412 = zext nneg i32 %43 to i64
- %xtraiter499 = and i64 %wide.trip.count412, 3
+ br i1 %38, label %sw.epilog199.loopexit482.unr-lcssa, label %for.body138.preheader.new
+
+for.body138.preheader.new: ; preds = %for.body138.preheader
+ %unroll_iter505 = and i64 %wide.trip.count416, 2147483644
+ br label %for.body138
+
+for.body138: ; preds = %for.body138, %for.body138.preheader.new
+ %indvars.iv412 = phi i64 [ 0, %for.body138.preheader.new ], [ %indvars.iv.next413.3, %for.body138 ]
+ %niter506 = phi i64 [ 0, %for.body138.preheader.new ], [ %niter506.next.3, %for.body138 ]
+ %indvars.iv.next413 = or disjoint i64 %indvars.iv412, 1
+ %indvars414 = trunc i64 %indvars.iv.next413 to i32
+ %39 = trunc nuw nsw i64 %indvars.iv412 to i32
+ %add140 = mul i32 %indvars414, %39
+ %add141 = or disjoint i32 %add140, 3
+ %arrayidx143 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv412
+ store i32 %add141, ptr %arrayidx143, align 8, !tbaa !4
+ %indvars.iv.next413.1 = or disjoint i64 %indvars.iv412, 2
+ %indvars414.1 = trunc i64 %indvars.iv.next413.1 to i32
+ %40 = trunc nuw nsw i64 %indvars.iv.next413 to i32
+ %add140.1 = mul i32 %indvars414.1, %40
+ %add141.1 = add nsw i32 %add140.1, 3
+ %arrayidx143.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next413
+ store i32 %add141.1, ptr %arrayidx143.1, align 4, !tbaa !4
+ %indvars.iv.next413.2 = or disjoint i64 %indvars.iv412, 3
+ %indvars414.2 = trunc i64 %indvars.iv.next413.2 to i32
+ %41 = trunc nuw nsw i64 %indvars.iv.next413.1 to i32
+ %add140.2 = mul i32 %indvars414.2, %41
+ %add141.2 = add nsw i32 %add140.2, 3
+ %arrayidx143.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next413.1
+ store i32 %add141.2, ptr %arrayidx143.2, align 8, !tbaa !4
+ %indvars.iv.next413.3 = add nuw nsw i64 %indvars.iv412, 4
+ %indvars414.3 = trunc i64 %indvars.iv.next413.3 to i32
+ %42 = trunc nuw nsw i64 %indvars.iv.next413.2 to i32
+ %add140.3 = mul i32 %indvars414.3, %42
+ %add141.3 = or disjoint i32 %add140.3, 3
+ %arrayidx143.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next413.2
+ store i32 %add141.3, ptr %arrayidx143.3, align 4, !tbaa !4
+ %niter506.next.3 = add i64 %niter506, 4
+ %niter506.ncmp.3 = icmp eq i64 %niter506.next.3, %unroll_iter505
+ br i1 %niter506.ncmp.3, label %sw.epilog199.loopexit482.unr-lcssa, label %for.body138, !llvm.loop !24
+
+sw.bb147: ; preds = %for.cond.cleanup102
+ %puts313 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
+ %43 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp151358 = icmp sgt i32 %43, 0
+ br i1 %cmp151358, label %for.body154.preheader, label %sw.epilog199
+
+for.body154.preheader: ; preds = %sw.bb147
+ %wide.trip.count410 = zext nneg i32 %43 to i64
+ %xtraiter497 = and i64 %wide.trip.count410, 3
%44 = icmp ult i32 %43, 4
- br i1 %44, label %sw.epilog201.loopexit485.unr-lcssa, label %for.body156.preheader.new
-
-for.body156.preheader.new: ; preds = %for.body156.preheader
- %unroll_iter502 = and i64 %wide.trip.count412, 2147483644
- br label %for.body156
-
-for.body156: ; preds = %for.body156, %for.body156.preheader.new
- %indvars.iv407 = phi i64 [ 0, %for.body156.preheader.new ], [ %indvars.iv.next408.3, %for.body156 ]
- %niter503 = phi i64 [ 0, %for.body156.preheader.new ], [ %niter503.next.3, %for.body156 ]
- %45 = trunc nuw nsw i64 %indvars.iv407 to i32
- %mul158316 = mul i32 %45, %45
- %46 = trunc i64 %indvars.iv407 to i32
+ br i1 %44, label %sw.epilog199.loopexit483.unr-lcssa, label %for.body154.preheader.new
+
+for.body154.preheader.new: ; preds = %for.body154.preheader
+ %unroll_iter500 = and i64 %wide.trip.count410, 2147483644
+ br label %for.body154
+
+for.body154: ; preds = %for.body154, %for.body154.preheader.new
+ %indvars.iv405 = phi i64 [ 0, %for.body154.preheader.new ], [ %indvars.iv.next406.3, %for.body154 ]
+ %niter501 = phi i64 [ 0, %for.body154.preheader.new ], [ %niter501.next.3, %for.body154 ]
+ %45 = trunc nuw nsw i64 %indvars.iv405 to i32
+ %mul156314 = mul i32 %45, %45
+ %46 = trunc i64 %indvars.iv405 to i32
%47 = add i32 %46, -1
- %sub160 = mul i32 %mul158316, %47
- %arrayidx162 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv407
- store i32 %sub160, ptr %arrayidx162, align 8, !tbaa !4
- %indvars.iv.next408 = or disjoint i64 %indvars.iv407, 1
- %48 = trunc nuw nsw i64 %indvars.iv.next408 to i32
- %mul158316.1 = mul i32 %48, %48
- %49 = trunc i64 %indvars.iv.next408 to i32
+ %sub158 = mul i32 %mul156314, %47
+ %arrayidx160 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv405
+ store i32 %sub158, ptr %arrayidx160, align 8, !tbaa !4
+ %indvars.iv.next406 = or disjoint i64 %indvars.iv405, 1
+ %48 = trunc nuw nsw i64 %indvars.iv.next406 to i32
+ %mul156314.1 = mul i32 %48, %48
+ %49 = trunc i64 %indvars.iv.next406 to i32
%50 = add nsw i32 %49, -1
- %sub160.1 = mul i32 %mul158316.1, %50
- %arrayidx162.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408
- store i32 %sub160.1, ptr %arrayidx162.1, align 4, !tbaa !4
- %indvars.iv.next408.1 = or disjoint i64 %indvars.iv407, 2
- %51 = trunc nuw nsw i64 %indvars.iv.next408.1 to i32
- %mul158316.2 = mul i32 %51, %51
- %52 = trunc i64 %indvars.iv.next408.1 to i32
+ %sub158.1 = mul i32 %mul156314.1, %50
+ %arrayidx160.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next406
+ store i32 %sub158.1, ptr %arrayidx160.1, align 4, !tbaa !4
+ %indvars.iv.next406.1 = or disjoint i64 %indvars.iv405, 2
+ %51 = trunc nuw nsw i64 %indvars.iv.next406.1 to i32
+ %mul156314.2 = mul i32 %51, %51
+ %52 = trunc i64 %indvars.iv.next406.1 to i32
%53 = add nsw i32 %52, -1
- %sub160.2 = mul i32 %mul158316.2, %53
- %arrayidx162.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408.1
- store i32 %sub160.2, ptr %arrayidx162.2, align 8, !tbaa !4
- %indvars.iv.next408.2 = or disjoint i64 %indvars.iv407, 3
- %54 = trunc nuw nsw i64 %indvars.iv.next408.2 to i32
- %mul158316.3 = mul i32 %54, %54
- %55 = trunc i64 %indvars.iv.next408.2 to i32
+ %sub158.2 = mul i32 %mul156314.2, %53
+ %arrayidx160.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next406.1
+ store i32 %sub158.2, ptr %arrayidx160.2, align 8, !tbaa !4
+ %indvars.iv.next406.2 = or disjoint i64 %indvars.iv405, 3
+ %54 = trunc nuw nsw i64 %indvars.iv.next406.2 to i32
+ %mul156314.3 = mul i32 %54, %54
+ %55 = trunc i64 %indvars.iv.next406.2 to i32
%56 = add nsw i32 %55, -1
- %sub160.3 = mul i32 %mul158316.3, %56
- %arrayidx162.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408.2
- store i32 %sub160.3, ptr %arrayidx162.3, align 4, !tbaa !4
- %indvars.iv.next408.3 = add nuw nsw i64 %indvars.iv407, 4
- %niter503.next.3 = add i64 %niter503, 4
- %niter503.ncmp.3 = icmp eq i64 %niter503.next.3, %unroll_iter502
- br i1 %niter503.ncmp.3, label %sw.epilog201.loopexit485.unr-lcssa, label %for.body156, !llvm.loop !25
-
-sw.bb166: ; preds = %for.cond.cleanup104
- %puts311 = call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
- %57 = load i32, ptr %len, align 4, !tbaa !4
- %cmp170358 = icmp sgt i32 %57, 0
- br i1 %cmp170358, label %for.body173.preheader, label %sw.epilog201
-
-for.body173.preheader: ; preds = %sw.bb166
- %wide.trip.count405 = zext nneg i32 %57 to i64
- %xtraiter494 = and i64 %wide.trip.count405, 3
+ %sub158.3 = mul i32 %mul156314.3, %56
+ %arrayidx160.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next406.2
+ store i32 %sub158.3, ptr %arrayidx160.3, align 4, !tbaa !4
+ %indvars.iv.next406.3 = add nuw nsw i64 %indvars.iv405, 4
+ %niter501.next.3 = add i64 %niter501, 4
+ %niter501.ncmp.3 = icmp eq i64 %niter501.next.3, %unroll_iter500
+ br i1 %niter501.ncmp.3, label %sw.epilog199.loopexit483.unr-lcssa, label %for.body154, !llvm.loop !25
+
+sw.bb164: ; preds = %for.cond.cleanup102
+ %puts309 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.27)
+ %57 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp168356 = icmp sgt i32 %57, 0
+ br i1 %cmp168356, label %for.body171.preheader, label %sw.epilog199
+
+for.body171.preheader: ; preds = %sw.bb164
+ %wide.trip.count403 = zext nneg i32 %57 to i64
+ %xtraiter492 = and i64 %wide.trip.count403, 3
%58 = icmp ult i32 %57, 4
- br i1 %58, label %sw.epilog201.loopexit486.unr-lcssa, label %for.body173.preheader.new
-
-for.body173.preheader.new: ; preds = %for.body173.preheader
- %unroll_iter497 = and i64 %wide.trip.count405, 2147483644
- br label %for.body173
-
-for.body173: ; preds = %for.body173, %for.body173.preheader.new
- %indvars.iv401 = phi i64 [ 0, %for.body173.preheader.new ], [ %indvars.iv.next402.3, %for.body173 ]
- %niter498 = phi i64 [ 0, %for.body173.preheader.new ], [ %niter498.next.3, %for.body173 ]
- %indvars.iv.next402 = or disjoint i64 %indvars.iv401, 1
- %indvars403 = trunc i64 %indvars.iv.next402 to i32
- %59 = trunc nuw nsw i64 %indvars.iv401 to i32
- %mul175312 = mul i32 %indvars403, %59
- %add177314 = or disjoint i32 %mul175312, 3
- %add179 = mul i32 %add177314, %59
- %arrayidx181 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv401
- store i32 %add179, ptr %arrayidx181, align 8, !tbaa !4
- %indvars.iv.next402.1 = or disjoint i64 %indvars.iv401, 2
- %indvars403.1 = trunc i64 %indvars.iv.next402.1 to i32
- %60 = trunc nuw nsw i64 %indvars.iv.next402 to i32
- %mul175312.1 = mul i32 %indvars403.1, %60
- %add177314.1 = add i32 %mul175312.1, 3
- %add179.1 = mul i32 %add177314.1, %60
- %arrayidx181.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402
- store i32 %add179.1, ptr %arrayidx181.1, align 4, !tbaa !4
- %indvars.iv.next402.2 = or disjoint i64 %indvars.iv401, 3
- %indvars403.2 = trunc i64 %indvars.iv.next402.2 to i32
- %61 = trunc nuw nsw i64 %indvars.iv.next402.1 to i32
- %mul175312.2 = mul i32 %indvars403.2, %61
- %add177314.2 = add i32 %mul175312.2, 3
- %add179.2 = mul i32 %add177314.2, %61
- %arrayidx181.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402.1
- store i32 %add179.2, ptr %arrayidx181.2, align 8, !tbaa !4
- %indvars.iv.next402.3 = add nuw nsw i64 %indvars.iv401, 4
- %indvars403.3 = trunc i64 %indvars.iv.next402.3 to i32
- %62 = trunc nuw nsw i64 %indvars.iv.next402.2 to i32
- %mul175312.3 = mul i32 %indvars403.3, %62
- %add177314.3 = or disjoint i32 %mul175312.3, 3
- %add179.3 = mul i32 %add177314.3, %62
- %arrayidx181.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402.2
- store i32 %add179.3, ptr %arrayidx181.3, align 4, !tbaa !4
- %niter498.next.3 = add i64 %niter498, 4
- %niter498.ncmp.3 = icmp eq i64 %niter498.next.3, %unroll_iter497
- br i1 %niter498.ncmp.3, label %sw.epilog201.loopexit486.unr-lcssa, label %for.body173, !llvm.loop !26
-
-sw.bb185: ; preds = %for.cond.cleanup104
- %puts309 = call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
- %63 = load i32, ptr %len, align 4, !tbaa !4
- %cmp189356 = icmp sgt i32 %63, 0
- br i1 %cmp189356, label %for.body192.preheader, label %sw.epilog201
-
-for.body192.preheader: ; preds = %sw.bb185
- %wide.trip.count399 = zext nneg i32 %63 to i64
- %xtraiter489 = and i64 %wide.trip.count399, 3
+ br i1 %58, label %sw.epilog199.loopexit484.unr-lcssa, label %for.body171.preheader.new
+
+for.body171.preheader.new: ; preds = %for.body171.preheader
+ %unroll_iter495 = and i64 %wide.trip.count403, 2147483644
+ br label %for.body171
+
+for.body171: ; preds = %for.body171, %for.body171.preheader.new
+ %indvars.iv399 = phi i64 [ 0, %for.body171.preheader.new ], [ %indvars.iv.next400.3, %for.body171 ]
+ %niter496 = phi i64 [ 0, %for.body171.preheader.new ], [ %niter496.next.3, %for.body171 ]
+ %indvars.iv.next400 = or disjoint i64 %indvars.iv399, 1
+ %indvars401 = trunc i64 %indvars.iv.next400 to i32
+ %59 = trunc nuw nsw i64 %indvars.iv399 to i32
+ %mul173310 = mul i32 %indvars401, %59
+ %add175312 = or disjoint i32 %mul173310, 3
+ %add177 = mul i32 %add175312, %59
+ %arrayidx179 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv399
+ store i32 %add177, ptr %arrayidx179, align 8, !tbaa !4
+ %indvars.iv.next400.1 = or disjoint i64 %indvars.iv399, 2
+ %indvars401.1 = trunc i64 %indvars.iv.next400.1 to i32
+ %60 = trunc nuw nsw i64 %indvars.iv.next400 to i32
+ %mul173310.1 = mul i32 %indvars401.1, %60
+ %add175312.1 = add i32 %mul173310.1, 3
+ %add177.1 = mul i32 %add175312.1, %60
+ %arrayidx179.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next400
+ store i32 %add177.1, ptr %arrayidx179.1, align 4, !tbaa !4
+ %indvars.iv.next400.2 = or disjoint i64 %indvars.iv399, 3
+ %indvars401.2 = trunc i64 %indvars.iv.next400.2 to i32
+ %61 = trunc nuw nsw i64 %indvars.iv.next400.1 to i32
+ %mul173310.2 = mul i32 %indvars401.2, %61
+ %add175312.2 = add i32 %mul173310.2, 3
+ %add177.2 = mul i32 %add175312.2, %61
+ %arrayidx179.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next400.1
+ store i32 %add177.2, ptr %arrayidx179.2, align 8, !tbaa !4
+ %indvars.iv.next400.3 = add nuw nsw i64 %indvars.iv399, 4
+ %indvars401.3 = trunc i64 %indvars.iv.next400.3 to i32
+ %62 = trunc nuw nsw i64 %indvars.iv.next400.2 to i32
+ %mul173310.3 = mul i32 %indvars401.3, %62
+ %add175312.3 = or disjoint i32 %mul173310.3, 3
+ %add177.3 = mul i32 %add175312.3, %62
+ %arrayidx179.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next400.2
+ store i32 %add177.3, ptr %arrayidx179.3, align 4, !tbaa !4
+ %niter496.next.3 = add i64 %niter496, 4
+ %niter496.ncmp.3 = icmp eq i64 %niter496.next.3, %unroll_iter495
+ br i1 %niter496.ncmp.3, label %sw.epilog199.loopexit484.unr-lcssa, label %for.body171, !llvm.loop !26
+
+sw.bb183: ; preds = %for.cond.cleanup102
+ %puts307 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.26)
+ %63 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp187354 = icmp sgt i32 %63, 0
+ br i1 %cmp187354, label %for.body190.preheader, label %sw.epilog199
+
+for.body190.preheader: ; preds = %sw.bb183
+ %wide.trip.count397 = zext nneg i32 %63 to i64
+ %xtraiter487 = and i64 %wide.trip.count397, 3
%64 = icmp ult i32 %63, 4
- br i1 %64, label %sw.epilog201.loopexit487.unr-lcssa, label %for.body192.preheader.new
-
-for.body192.preheader.new: ; preds = %for.body192.preheader
- %unroll_iter492 = and i64 %wide.trip.count399, 2147483644
- br label %for.body192
-
-for.body192: ; preds = %for.body192, %for.body192.preheader.new
- %indvars.iv394 = phi i64 [ 0, %for.body192.preheader.new ], [ %indvars.iv.next395.3, %for.body192 ]
- %niter493 = phi i64 [ 0, %for.body192.preheader.new ], [ %niter493.next.3, %for.body192 ]
- %indvars398 = trunc i64 %indvars.iv394 to i32
- %mul194310 = or disjoint i32 %indvars398, 3
- %add195 = mul i32 %mul194310, %indvars398
- %arrayidx197 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv394
- store i32 %add195, ptr %arrayidx197, align 8, !tbaa !4
- %indvars.iv.next395 = or disjoint i64 %indvars.iv394, 1
- %indvars398.1 = trunc i64 %indvars.iv.next395 to i32
- %mul194310.1 = add nuw i32 %indvars398.1, 3
- %add195.1 = mul i32 %mul194310.1, %indvars398.1
- %arrayidx197.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395
- store i32 %add195.1, ptr %arrayidx197.1, align 4, !tbaa !4
- %indvars.iv.next395.1 = or disjoint i64 %indvars.iv394, 2
- %indvars398.2 = trunc i64 %indvars.iv.next395.1 to i32
- %mul194310.2 = add nuw i32 %indvars398.2, 3
- %add195.2 = mul i32 %mul194310.2, %indvars398.2
- %arrayidx197.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395.1
- store i32 %add195.2, ptr %arrayidx197.2, align 8, !tbaa !4
- %indvars.iv.next395.2 = or disjoint i64 %indvars.iv394, 3
- %indvars398.3 = trunc i64 %indvars.iv.next395.2 to i32
- %mul194310.3 = add nuw i32 %indvars398.3, 3
- %add195.3 = mul i32 %mul194310.3, %indvars398.3
- %arrayidx197.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395.2
- store i32 %add195.3, ptr %arrayidx197.3, align 4, !tbaa !4
- %indvars.iv.next395.3 = add nuw nsw i64 %indvars.iv394, 4
- %niter493.next.3 = add i64 %niter493, 4
- %niter493.ncmp.3 = icmp eq i64 %niter493.next.3, %unroll_iter492
- br i1 %niter493.ncmp.3, label %sw.epilog201.loopexit487.unr-lcssa, label %for.body192, !llvm.loop !27
-
-sw.epilog201.loopexit.unr-lcssa: ; preds = %for.body120, %for.body120.preheader
- %indvars.iv420.unr = phi i64 [ 0, %for.body120.preheader ], [ %indvars.iv.next421.3, %for.body120 ]
- %lcmp.mod511.not = icmp eq i64 %xtraiter509, 0
- br i1 %lcmp.mod511.not, label %sw.epilog201, label %for.body120.epil
-
-for.body120.epil: ; preds = %sw.epilog201.loopexit.unr-lcssa, %for.body120.epil
- %indvars.iv420.epil = phi i64 [ %indvars.iv.next421.epil, %for.body120.epil ], [ %indvars.iv420.unr, %sw.epilog201.loopexit.unr-lcssa ]
- %epil.iter510 = phi i64 [ %epil.iter510.next, %for.body120.epil ], [ 0, %sw.epilog201.loopexit.unr-lcssa ]
- %indvars425.epil = trunc i64 %indvars.iv420.epil to i32
- %mul121.epil = mul nuw nsw i32 %indvars425.epil, %indvars425.epil
- %mul122322.epil = add nuw i32 %mul121.epil, 1
- %mul123321.epil = mul i32 %mul122322.epil, %indvars425.epil
- %add125323.epil = add i32 %mul123321.epil, 3
- %add127.epil = mul i32 %add125323.epil, %indvars425.epil
- %arrayidx129.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv420.epil
- store i32 %add127.epil, ptr %arrayidx129.epil, align 4, !tbaa !4
- %indvars.iv.next421.epil = add nuw nsw i64 %indvars.iv420.epil, 1
- %epil.iter510.next = add i64 %epil.iter510, 1
- %epil.iter510.cmp.not = icmp eq i64 %epil.iter510.next, %xtraiter509
- br i1 %epil.iter510.cmp.not, label %sw.epilog201, label %for.body120.epil, !llvm.loop !28
-
-sw.epilog201.loopexit484.unr-lcssa: ; preds = %for.body140, %for.body140.preheader
- %indvars.iv414.unr = phi i64 [ 0, %for.body140.preheader ], [ %indvars.iv.next415.3, %for.body140 ]
- %lcmp.mod506.not = icmp eq i64 %xtraiter504, 0
- br i1 %lcmp.mod506.not, label %sw.epilog201, label %for.body140.epil
-
-for.body140.epil: ; preds = %sw.epilog201.loopexit484.unr-lcssa, %for.body140.epil
- %indvars.iv414.epil = phi i64 [ %indvars.iv.next415.epil, %for.body140.epil ], [ %indvars.iv414.unr, %sw.epilog201.loopexit484.unr-lcssa ]
- %epil.iter505 = phi i64 [ %epil.iter505.next, %for.body140.epil ], [ 0, %sw.epilog201.loopexit484.unr-lcssa ]
- %indvars.iv.next415.epil = add nuw nsw i64 %indvars.iv414.epil, 1
- %indvars416.epil = trunc i64 %indvars.iv.next415.epil to i32
- %65 = trunc nuw nsw i64 %indvars.iv414.epil to i32
- %add142.epil = mul i32 %indvars416.epil, %65
- %add143.epil = add nsw i32 %add142.epil, 3
- %arrayidx145.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv414.epil
- store i32 %add143.epil, ptr %arrayidx145.epil, align 4, !tbaa !4
- %epil.iter505.next = add i64 %epil.iter505, 1
- %epil.iter505.cmp.not = icmp eq i64 %epil.iter505.next, %xtraiter504
- br i1 %epil.iter505.cmp.not, label %sw.epilog201, label %for.body140.epil, !llvm.loop !29
-
-sw.epilog201.loopexit485.unr-lcssa: ; preds = %for.body156, %for.body156.preheader
- %indvars.iv407.unr = phi i64 [ 0, %for.body156.preheader ], [ %indvars.iv.next408.3, %for.body156 ]
- %lcmp.mod501.not = icmp eq i64 %xtraiter499, 0
- br i1 %lcmp.mod501.not, label %sw.epilog201, label %for.body156.epil
-
-for.body156.epil: ; preds = %sw.epilog201.loopexit485.unr-lcssa, %for.body156.epil
- %indvars.iv407.epil = phi i64 [ %indvars.iv.next408.epil, %for.body156.epil ], [ %indvars.iv407.unr, %sw.epilog201.loopexit485.unr-lcssa ]
- %epil.iter500 = phi i64 [ %epil.iter500.next, %for.body156.epil ], [ 0, %sw.epilog201.loopexit485.unr-lcssa ]
- %66 = trunc nuw nsw i64 %indvars.iv407.epil to i32
- %mul158316.epil = mul i32 %66, %66
- %67 = trunc i64 %indvars.iv407.epil to i32
+ br i1 %64, label %sw.epilog199.loopexit485.unr-lcssa, label %for.body190.preheader.new
+
+for.body190.preheader.new: ; preds = %for.body190.preheader
+ %unroll_iter490 = and i64 %wide.trip.count397, 2147483644
+ br label %for.body190
+
+for.body190: ; preds = %for.body190, %for.body190.preheader.new
+ %indvars.iv392 = phi i64 [ 0, %for.body190.preheader.new ], [ %indvars.iv.next393.3, %for.body190 ]
+ %niter491 = phi i64 [ 0, %for.body190.preheader.new ], [ %niter491.next.3, %for.body190 ]
+ %indvars396 = trunc i64 %indvars.iv392 to i32
+ %mul192308 = or disjoint i32 %indvars396, 3
+ %add193 = mul i32 %mul192308, %indvars396
+ %arrayidx195 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv392
+ store i32 %add193, ptr %arrayidx195, align 8, !tbaa !4
+ %indvars.iv.next393 = or disjoint i64 %indvars.iv392, 1
+ %indvars396.1 = trunc i64 %indvars.iv.next393 to i32
+ %mul192308.1 = add nuw i32 %indvars396.1, 3
+ %add193.1 = mul i32 %mul192308.1, %indvars396.1
+ %arrayidx195.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next393
+ store i32 %add193.1, ptr %arrayidx195.1, align 4, !tbaa !4
+ %indvars.iv.next393.1 = or disjoint i64 %indvars.iv392, 2
+ %indvars396.2 = trunc i64 %indvars.iv.next393.1 to i32
+ %mul192308.2 = add nuw i32 %indvars396.2, 3
+ %add193.2 = mul i32 %mul192308.2, %indvars396.2
+ %arrayidx195.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next393.1
+ store i32 %add193.2, ptr %arrayidx195.2, align 8, !tbaa !4
+ %indvars.iv.next393.2 = or disjoint i64 %indvars.iv392, 3
+ %indvars396.3 = trunc i64 %indvars.iv.next393.2 to i32
+ %mul192308.3 = add nuw i32 %indvars396.3, 3
+ %add193.3 = mul i32 %mul192308.3, %indvars396.3
+ %arrayidx195.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next393.2
+ store i32 %add193.3, ptr %arrayidx195.3, align 4, !tbaa !4
+ %indvars.iv.next393.3 = add nuw nsw i64 %indvars.iv392, 4
+ %niter491.next.3 = add i64 %niter491, 4
+ %niter491.ncmp.3 = icmp eq i64 %niter491.next.3, %unroll_iter490
+ br i1 %niter491.ncmp.3, label %sw.epilog199.loopexit485.unr-lcssa, label %for.body190, !llvm.loop !27
+
+sw.epilog199.loopexit.unr-lcssa: ; preds = %for.body118, %for.body118.preheader
+ %indvars.iv418.unr = phi i64 [ 0, %for.body118.preheader ], [ %indvars.iv.next419.3, %for.body118 ]
+ %lcmp.mod509.not = icmp eq i64 %xtraiter507, 0
+ br i1 %lcmp.mod509.not, label %sw.epilog199, label %for.body118.epil
+
+for.body118.epil: ; preds = %sw.epilog199.loopexit.unr-lcssa, %for.body118.epil
+ %indvars.iv418.epil = phi i64 [ %indvars.iv.next419.epil, %for.body118.epil ], [ %indvars.iv418.unr, %sw.epilog199.loopexit.unr-lcssa ]
+ %epil.iter508 = phi i64 [ %epil.iter508.next, %for.body118.epil ], [ 0, %sw.epilog199.loopexit.unr-lcssa ]
+ %indvars423.epil = trunc i64 %indvars.iv418.epil to i32
+ %mul119.epil = mul nuw nsw i32 %indvars423.epil, %indvars423.epil
+ %mul120320.epil = add nuw i32 %mul119.epil, 1
+ %mul121319.epil = mul i32 %mul120320.epil, %indvars423.epil
+ %add123321.epil = add i32 %mul121319.epil, 3
+ %add125.epil = mul i32 %add123321.epil, %indvars423.epil
+ %arrayidx127.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv418.epil
+ store i32 %add125.epil, ptr %arrayidx127.epil, align 4, !tbaa !4
+ %indvars.iv.next419.epil = add nuw nsw i64 %indvars.iv418.epil, 1
+ %epil.iter508.next = add i64 %epil.iter508, 1
+ %epil.iter508.cmp.not = icmp eq i64 %epil.iter508.next, %xtraiter507
+ br i1 %epil.iter508.cmp.not, label %sw.epilog199, label %for.body118.epil, !llvm.loop !28
+
+sw.epilog199.loopexit482.unr-lcssa: ; preds = %for.body138, %for.body138.preheader
+ %indvars.iv412.unr = phi i64 [ 0, %for.body138.preheader ], [ %indvars.iv.next413.3, %for.body138 ]
+ %lcmp.mod504.not = icmp eq i64 %xtraiter502, 0
+ br i1 %lcmp.mod504.not, label %sw.epilog199, label %for.body138.epil
+
+for.body138.epil: ; preds = %sw.epilog199.loopexit482.unr-lcssa, %for.body138.epil
+ %indvars.iv412.epil = phi i64 [ %indvars.iv.next413.epil, %for.body138.epil ], [ %indvars.iv412.unr, %sw.epilog199.loopexit482.unr-lcssa ]
+ %epil.iter503 = phi i64 [ %epil.iter503.next, %for.body138.epil ], [ 0, %sw.epilog199.loopexit482.unr-lcssa ]
+ %indvars.iv.next413.epil = add nuw nsw i64 %indvars.iv412.epil, 1
+ %indvars414.epil = trunc i64 %indvars.iv.next413.epil to i32
+ %65 = trunc nuw nsw i64 %indvars.iv412.epil to i32
+ %add140.epil = mul i32 %indvars414.epil, %65
+ %add141.epil = add nsw i32 %add140.epil, 3
+ %arrayidx143.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv412.epil
+ store i32 %add141.epil, ptr %arrayidx143.epil, align 4, !tbaa !4
+ %epil.iter503.next = add i64 %epil.iter503, 1
+ %epil.iter503.cmp.not = icmp eq i64 %epil.iter503.next, %xtraiter502
+ br i1 %epil.iter503.cmp.not, label %sw.epilog199, label %for.body138.epil, !llvm.loop !29
+
+sw.epilog199.loopexit483.unr-lcssa: ; preds = %for.body154, %for.body154.preheader
+ %indvars.iv405.unr = phi i64 [ 0, %for.body154.preheader ], [ %indvars.iv.next406.3, %for.body154 ]
+ %lcmp.mod499.not = icmp eq i64 %xtraiter497, 0
+ br i1 %lcmp.mod499.not, label %sw.epilog199, label %for.body154.epil
+
+for.body154.epil: ; preds = %sw.epilog199.loopexit483.unr-lcssa, %for.body154.epil
+ %indvars.iv405.epil = phi i64 [ %indvars.iv.next406.epil, %for.body154.epil ], [ %indvars.iv405.unr, %sw.epilog199.loopexit483.unr-lcssa ]
+ %epil.iter498 = phi i64 [ %epil.iter498.next, %for.body154.epil ], [ 0, %sw.epilog199.loopexit483.unr-lcssa ]
+ %66 = trunc nuw nsw i64 %indvars.iv405.epil to i32
+ %mul156314.epil = mul i32 %66, %66
+ %67 = trunc i64 %indvars.iv405.epil to i32
%68 = add i32 %67, -1
- %sub160.epil = mul i32 %mul158316.epil, %68
- %arrayidx162.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv407.epil
- store i32 %sub160.epil, ptr %arrayidx162.epil, align 4, !tbaa !4
- %indvars.iv.next408.epil = add nuw nsw i64 %indvars.iv407.epil, 1
- %epil.iter500.next = add i64 %epil.iter500, 1
- %epil.iter500.cmp.not = icmp eq i64 %epil.iter500.next, %xtraiter499
- br i1 %epil.iter500.cmp.not, label %sw.epilog201, label %for.body156.epil, !llvm.loop !30
-
-sw.epilog201.loopexit486.unr-lcssa: ; preds = %for.body173, %for.body173.preheader
- %indvars.iv401.unr = phi i64 [ 0, %for.body173.preheader ], [ %indvars.iv.next402.3, %for.body173 ]
- %lcmp.mod496.not = icmp eq i64 %xtraiter494, 0
- br i1 %lcmp.mod496.not, label %sw.epilog201, label %for.body173.epil
-
-for.body173.epil: ; preds = %sw.epilog201.loopexit486.unr-lcssa, %for.body173.epil
- %indvars.iv401.epil = phi i64 [ %indvars.iv.next402.epil, %for.body173.epil ], [ %indvars.iv401.unr, %sw.epilog201.loopexit486.unr-lcssa ]
- %epil.iter495 = phi i64 [ %epil.iter495.next, %for.body173.epil ], [ 0, %sw.epilog201.loopexit486.unr-lcssa ]
- %indvars.iv.next402.epil = add nuw nsw i64 %indvars.iv401.epil, 1
- %indvars403.epil = trunc i64 %indvars.iv.next402.epil to i32
- %69 = trunc nuw nsw i64 %indvars.iv401.epil to i32
- %mul175312.epil = mul i32 %indvars403.epil, %69
- %add177314.epil = add i32 %mul175312.epil, 3
- %add179.epil = mul i32 %add177314.epil, %69
- %arrayidx181.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv401.epil
- store i32 %add179.epil, ptr %arrayidx181.epil, align 4, !tbaa !4
- %epil.iter495.next = add i64 %epil.iter495, 1
- %epil.iter495.cmp.not = icmp eq i64 %epil.iter495.next, %xtraiter494
- br i1 %epil.iter495.cmp.not, label %sw.epilog201, label %for.body173.epil, !llvm.loop !31
-
-sw.epilog201.loopexit487.unr-lcssa: ; preds = %for.body192, %for.body192.preheader
- %indvars.iv394.unr = phi i64 [ 0, %for.body192.preheader ], [ %indvars.iv.next395.3, %for.body192 ]
- %lcmp.mod491.not = icmp eq i64 %xtraiter489, 0
- br i1 %lcmp.mod491.not, label %sw.epilog201, label %for.body192.epil
-
-for.body192.epil: ; preds = %sw.epilog201.loopexit487.unr-lcssa, %for.body192.epil
- %indvars.iv394.epil = phi i64 [ %indvars.iv.next395.epil, %for.body192.epil ], [ %indvars.iv394.unr, %sw.epilog201.loopexit487.unr-lcssa ]
- %epil.iter490 = phi i64 [ %epil.iter490.next, %for.body192.epil ], [ 0, %sw.epilog201.loopexit487.unr-lcssa ]
- %indvars398.epil = trunc i64 %indvars.iv394.epil to i32
- %mul194310.epil = add nuw i32 %indvars398.epil, 3
- %add195.epil = mul i32 %mul194310.epil, %indvars398.epil
- %arrayidx197.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv394.epil
- store i32 %add195.epil, ptr %arrayidx197.epil, align 4, !tbaa !4
- %indvars.iv.next395.epil = add nuw nsw i64 %indvars.iv394.epil, 1
- %epil.iter490.next = add i64 %epil.iter490, 1
- %epil.iter490.cmp.not = icmp eq i64 %epil.iter490.next, %xtraiter489
- br i1 %epil.iter490.cmp.not, label %sw.epilog201, label %for.body192.epil, !llvm.loop !32
-
-sw.epilog201: ; preds = %sw.epilog201.loopexit487.unr-lcssa, %for.body192.epil, %sw.epilog201.loopexit486.unr-lcssa, %for.body173.epil, %sw.epilog201.loopexit485.unr-lcssa, %for.body156.epil, %sw.epilog201.loopexit484.unr-lcssa, %for.body140.epil, %sw.epilog201.loopexit.unr-lcssa, %for.body120.epil, %sw.bb185, %sw.bb166, %sw.bb149, %sw.bb133, %sw.bb113, %for.cond.cleanup104
- call void @func3()
+ %sub158.epil = mul i32 %mul156314.epil, %68
+ %arrayidx160.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv405.epil
+ store i32 %sub158.epil, ptr %arrayidx160.epil, align 4, !tbaa !4
+ %indvars.iv.next406.epil = add nuw nsw i64 %indvars.iv405.epil, 1
+ %epil.iter498.next = add i64 %epil.iter498, 1
+ %epil.iter498.cmp.not = icmp eq i64 %epil.iter498.next, %xtraiter497
+ br i1 %epil.iter498.cmp.not, label %sw.epilog199, label %for.body154.epil, !llvm.loop !30
+
+sw.epilog199.loopexit484.unr-lcssa: ; preds = %for.body171, %for.body171.preheader
+ %indvars.iv399.unr = phi i64 [ 0, %for.body171.preheader ], [ %indvars.iv.next400.3, %for.body171 ]
+ %lcmp.mod494.not = icmp eq i64 %xtraiter492, 0
+ br i1 %lcmp.mod494.not, label %sw.epilog199, label %for.body171.epil
+
+for.body171.epil: ; preds = %sw.epilog199.loopexit484.unr-lcssa, %for.body171.epil
+ %indvars.iv399.epil = phi i64 [ %indvars.iv.next400.epil, %for.body171.epil ], [ %indvars.iv399.unr, %sw.epilog199.loopexit484.unr-lcssa ]
+ %epil.iter493 = phi i64 [ %epil.iter493.next, %for.body171.epil ], [ 0, %sw.epilog199.loopexit484.unr-lcssa ]
+ %indvars.iv.next400.epil = add nuw nsw i64 %indvars.iv399.epil, 1
+ %indvars401.epil = trunc i64 %indvars.iv.next400.epil to i32
+ %69 = trunc nuw nsw i64 %indvars.iv399.epil to i32
+ %mul173310.epil = mul i32 %indvars401.epil, %69
+ %add175312.epil = add i32 %mul173310.epil, 3
+ %add177.epil = mul i32 %add175312.epil, %69
+ %arrayidx179.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv399.epil
+ store i32 %add177.epil, ptr %arrayidx179.epil, align 4, !tbaa !4
+ %epil.iter493.next = add i64 %epil.iter493, 1
+ %epil.iter493.cmp.not = icmp eq i64 %epil.iter493.next, %xtraiter492
+ br i1 %epil.iter493.cmp.not, label %sw.epilog199, label %for.body171.epil, !llvm.loop !31
+
+sw.epilog199.loopexit485.unr-lcssa: ; preds = %for.body190, %for.body190.preheader
+ %indvars.iv392.unr = phi i64 [ 0, %for.body190.preheader ], [ %indvars.iv.next393.3, %for.body190 ]
+ %lcmp.mod489.not = icmp eq i64 %xtraiter487, 0
+ br i1 %lcmp.mod489.not, label %sw.epilog199, label %for.body190.epil
+
+for.body190.epil: ; preds = %sw.epilog199.loopexit485.unr-lcssa, %for.body190.epil
+ %indvars.iv392.epil = phi i64 [ %indvars.iv.next393.epil, %for.body190.epil ], [ %indvars.iv392.unr, %sw.epilog199.loopexit485.unr-lcssa ]
+ %epil.iter488 = phi i64 [ %epil.iter488.next, %for.body190.epil ], [ 0, %sw.epilog199.loopexit485.unr-lcssa ]
+ %indvars396.epil = trunc i64 %indvars.iv392.epil to i32
+ %mul192308.epil = add nuw i32 %indvars396.epil, 3
+ %add193.epil = mul i32 %mul192308.epil, %indvars396.epil
+ %arrayidx195.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv392.epil
+ store i32 %add193.epil, ptr %arrayidx195.epil, align 4, !tbaa !4
+ %indvars.iv.next393.epil = add nuw nsw i64 %indvars.iv392.epil, 1
+ %epil.iter488.next = add i64 %epil.iter488, 1
+ %epil.iter488.cmp.not = icmp eq i64 %epil.iter488.next, %xtraiter487
+ br i1 %epil.iter488.cmp.not, label %sw.epilog199, label %for.body190.epil, !llvm.loop !32
+
+sw.epilog199: ; preds = %sw.epilog199.loopexit485.unr-lcssa, %for.body190.epil, %sw.epilog199.loopexit484.unr-lcssa, %for.body171.epil, %sw.epilog199.loopexit483.unr-lcssa, %for.body154.epil, %sw.epilog199.loopexit482.unr-lcssa, %for.body138.epil, %sw.epilog199.loopexit.unr-lcssa, %for.body118.epil, %sw.bb183, %sw.bb164, %sw.bb147, %sw.bb131, %sw.bb111, %for.cond.cleanup102
+ tail call void @func3()
unreachable
-if.else202: ; preds = %for.cond.cleanup
- %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
- %70 = load i32, ptr %len, align 4, !tbaa !4
- %cmp206352 = icmp sgt i32 %70, 0
- br i1 %cmp206352, label %for.body209, label %for.cond.cleanup208
+if.else200: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %70 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp204350 = icmp sgt i32 %70, 0
+ br i1 %cmp204350, label %for.body207, label %for.cond.cleanup206
-for.cond.cleanup208: ; preds = %for.body209, %if.else202
- call void @func2()
+for.cond.cleanup206: ; preds = %for.body207, %if.else200
+ tail call void @func2()
unreachable
-for.body209: ; preds = %if.else202, %for.body209
- %indvars.iv386 = phi i64 [ %indvars.iv.next387, %for.body209 ], [ 0, %if.else202 ]
- %arrayidx211 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv386
- %71 = load i32, ptr %arrayidx211, align 4, !tbaa !4
- %call212 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %71)
- %indvars.iv.next387 = add nuw nsw i64 %indvars.iv386, 1
- %72 = load i32, ptr %len, align 4, !tbaa !4
+for.body207: ; preds = %if.else200, %for.body207
+ %indvars.iv384 = phi i64 [ %indvars.iv.next385, %for.body207 ], [ 0, %if.else200 ]
+ %arrayidx209 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv384
+ %71 = load i32, ptr %arrayidx209, align 4, !tbaa !4
+ %call210 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %71)
+ %indvars.iv.next385 = add nuw nsw i64 %indvars.iv384, 1
+ %72 = load i32, ptr @len, align 4, !tbaa !4
%73 = sext i32 %72 to i64
- %cmp206 = icmp slt i64 %indvars.iv.next387, %73
- br i1 %cmp206, label %for.body209, label %for.cond.cleanup208, !llvm.loop !33
+ %cmp204 = icmp slt i64 %indvars.iv.next385, %73
+ br i1 %cmp204, label %for.body207, label %for.cond.cleanup206, !llvm.loop !33
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
-declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
-
-; Function Attrs: nofree nounwind
-declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
; Function Attrs: nounwind
-define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
entry:
-; CHECK: larl %r0, .LBB3_13
-; CHECK: stg %r0, 8(%r1)
-; CHECK: stg %r11, 0(%r1)
-; CHECK: stg %r15, 24(%r1)
-
%0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
%cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
- %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.34)
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
%call1 = tail call signext i32 @func1()
unreachable
if.else: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.33)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
ret i32 0
}
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #2 = { noreturn nounwind }
attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-attributes #5 = { nounwind }
-attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #7 = { nofree nounwind }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -998,7 +1004,7 @@ attributes #7 = { nofree nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
!4 = !{!5, !5, i64 0}
!5 = !{!"int", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-01.ll
new file mode 100644
index 00000000000000..3fdf813f853119
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-01.ll
@@ -0,0 +1,343 @@
+; This test case produces right result when alloca len is not local variable.
+; Test output of setjmp/longjmp with nested setjmp for alloca
+; Test for Frame Pointer in first slot in jmp_buf.
+
+; RUN: clang -O2 -mbackchain -o %t %s
+; RUN: %t 10 | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-01.c'
+source_filename = "builtin-setjmp-longjmp-alloca-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.13 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.14 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.15 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.16 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.17 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.18 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.19 = private unnamed_addr constant [30 x i8] c"Usage: program_name <length> \00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1(i32 noundef signext %len) local_unnamed_addr #3 {
+entry:
+ %conv = sext i32 %len to i64
+ %mul = shl nsw i64 %conv, 2
+ %0 = alloca i8, i64 %mul, align 8
+ %cmp84 = icmp sgt i32 %len, 0
+ br i1 %cmp84, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %wide.trip.count = zext nneg i32 %len to i64
+ %xtraiter = and i64 %wide.trip.count, 3
+ %1 = icmp ult i32 %len, 4
+ br i1 %1, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
+
+for.body.preheader.new: ; preds = %for.body.preheader
+ %unroll_iter = and i64 %wide.trip.count, 2147483644
+ br label %for.body
+
+for.cond.cleanup.loopexit.unr-lcssa: ; preds = %for.body, %for.body.preheader
+ %indvars.iv.unr = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next.3, %for.body ]
+ %lcmp.mod.not = icmp eq i64 %xtraiter, 0
+ br i1 %lcmp.mod.not, label %for.cond.cleanup, label %for.body.epil
+
+for.body.epil: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil
+ %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %for.body.epil ], [ %indvars.iv.unr, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
+ %indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
+ %indvars.epil = trunc i64 %indvars.iv.next.epil to i32
+ %2 = trunc nuw nsw i64 %indvars.iv.epil to i32
+ %add.epil = mul i32 %indvars.epil, %2
+ %arrayidx.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.epil
+ store i32 %add.epil, ptr %arrayidx.epil, align 4, !tbaa !4
+ %epil.iter.next = add i64 %epil.iter, 1
+ %epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
+ br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
+
+for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
+ %3 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %3, 0
+ br i1 %cmp3, label %if.then, label %if.else38
+
+for.body: ; preds = %for.body, %for.body.preheader.new
+ %indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
+ %niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
+ %indvars.iv.next = or disjoint i64 %indvars.iv, 1
+ %indvars = trunc i64 %indvars.iv.next to i32
+ %4 = trunc nuw nsw i64 %indvars.iv to i32
+ %add = mul i32 %indvars, %4
+ %arrayidx = getelementptr inbounds i32, ptr %0, i64 %indvars.iv
+ store i32 %add, ptr %arrayidx, align 8, !tbaa !4
+ %indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
+ %indvars.1 = trunc i64 %indvars.iv.next.1 to i32
+ %5 = trunc nuw nsw i64 %indvars.iv.next to i32
+ %add.1 = mul i32 %indvars.1, %5
+ %arrayidx.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next
+ store i32 %add.1, ptr %arrayidx.1, align 4, !tbaa !4
+ %indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
+ %indvars.2 = trunc i64 %indvars.iv.next.2 to i32
+ %6 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
+ %add.2 = mul i32 %indvars.2, %6
+ %arrayidx.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.1
+ store i32 %add.2, ptr %arrayidx.2, align 8, !tbaa !4
+ %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
+ %indvars.3 = trunc i64 %indvars.iv.next.3 to i32
+ %7 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
+ %add.3 = mul i32 %indvars.3, %7
+ %arrayidx.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.2
+ store i32 %add.3, ptr %arrayidx.3, align 4, !tbaa !4
+ %niter.next.3 = add i64 %niter, 4
+ %niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
+ br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
+
+if.then: ; preds = %for.cond.cleanup
+ %puts77 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %8 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %8, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 3
+; CHECK: arr: 14
+; CHECK: arr: 39
+; CHECK: arr: 84
+; CHECK: arr: 155
+; CHECK: arr: 258
+; CHECK: arr: 399
+; CHECK: arr: 584
+; CHECK: arr: 819
+
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts78 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ br i1 %cmp84, label %for.body15.preheader, label %for.cond.cleanup26
+
+for.body15.preheader: ; preds = %if.else
+ %wide.trip.count103 = zext nneg i32 %len to i64
+ br label %for.body15
+
+for.body27.preheader: ; preds = %for.body15
+ %xtraiter111 = and i64 %wide.trip.count103, 3
+ %9 = icmp ult i32 %len, 4
+ br i1 %9, label %for.cond.cleanup26.loopexit.unr-lcssa, label %for.body27.preheader.new
+
+for.body27.preheader.new: ; preds = %for.body27.preheader
+ %unroll_iter114 = and i64 %wide.trip.count103, 2147483644
+ br label %for.body27
+
+for.body15: ; preds = %for.body15.preheader, %for.body15
+ %indvars.iv99 = phi i64 [ 0, %for.body15.preheader ], [ %indvars.iv.next100, %for.body15 ]
+ %arrayidx17 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv99
+ %10 = load i32, ptr %arrayidx17, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %10)
+ %indvars.iv.next100 = add nuw nsw i64 %indvars.iv99, 1
+ %exitcond104.not = icmp eq i64 %indvars.iv.next100, %wide.trip.count103
+ br i1 %exitcond104.not, label %for.body27.preheader, label %for.body15, !llvm.loop !12
+
+for.cond.cleanup26.loopexit.unr-lcssa: ; preds = %for.body27, %for.body27.preheader
+ %indvars.iv105.unr = phi i64 [ 0, %for.body27.preheader ], [ %indvars.iv.next106.3, %for.body27 ]
+ %lcmp.mod113.not = icmp eq i64 %xtraiter111, 0
+ br i1 %lcmp.mod113.not, label %for.cond.cleanup26, label %for.body27.epil
+
+for.body27.epil: ; preds = %for.cond.cleanup26.loopexit.unr-lcssa, %for.body27.epil
+ %indvars.iv105.epil = phi i64 [ %indvars.iv.next106.epil, %for.body27.epil ], [ %indvars.iv105.unr, %for.cond.cleanup26.loopexit.unr-lcssa ]
+ %epil.iter112 = phi i64 [ %epil.iter112.next, %for.body27.epil ], [ 0, %for.cond.cleanup26.loopexit.unr-lcssa ]
+ %indvars.iv.next106.epil = add nuw nsw i64 %indvars.iv105.epil, 1
+ %indvars107.epil = trunc i64 %indvars.iv.next106.epil to i32
+ %11 = trunc nuw nsw i64 %indvars.iv105.epil to i32
+ %mul2979.epil = mul i32 %indvars107.epil, %11
+ %add3181.epil = add nuw nsw i32 %mul2979.epil, 1
+ %add32.epil = mul i32 %add3181.epil, %11
+ %arrayidx34.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv105.epil
+ store i32 %add32.epil, ptr %arrayidx34.epil, align 4, !tbaa !4
+ %epil.iter112.next = add i64 %epil.iter112, 1
+ %epil.iter112.cmp.not = icmp eq i64 %epil.iter112.next, %xtraiter111
+ br i1 %epil.iter112.cmp.not, label %for.cond.cleanup26, label %for.body27.epil, !llvm.loop !13
+
+for.cond.cleanup26: ; preds = %for.cond.cleanup26.loopexit.unr-lcssa, %for.body27.epil, %if.else
+ tail call void @func3()
+ unreachable
+
+for.body27: ; preds = %for.body27, %for.body27.preheader.new
+ %indvars.iv105 = phi i64 [ 0, %for.body27.preheader.new ], [ %indvars.iv.next106.3, %for.body27 ]
+ %niter115 = phi i64 [ 0, %for.body27.preheader.new ], [ %niter115.next.3, %for.body27 ]
+ %indvars.iv.next106 = or disjoint i64 %indvars.iv105, 1
+ %indvars107 = trunc i64 %indvars.iv.next106 to i32
+ %12 = trunc nuw nsw i64 %indvars.iv105 to i32
+ %mul2979 = mul i32 %indvars107, %12
+ %add3181 = or disjoint i32 %mul2979, 1
+ %add32 = mul i32 %add3181, %12
+ %arrayidx34 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv105
+ store i32 %add32, ptr %arrayidx34, align 8, !tbaa !4
+ %indvars.iv.next106.1 = or disjoint i64 %indvars.iv105, 2
+ %indvars107.1 = trunc i64 %indvars.iv.next106.1 to i32
+ %13 = trunc nuw nsw i64 %indvars.iv.next106 to i32
+ %mul2979.1 = mul i32 %indvars107.1, %13
+ %add3181.1 = or disjoint i32 %mul2979.1, 1
+ %add32.1 = mul i32 %add3181.1, %13
+ %arrayidx34.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106
+ store i32 %add32.1, ptr %arrayidx34.1, align 4, !tbaa !4
+ %indvars.iv.next106.2 = or disjoint i64 %indvars.iv105, 3
+ %indvars107.2 = trunc i64 %indvars.iv.next106.2 to i32
+ %14 = trunc nuw nsw i64 %indvars.iv.next106.1 to i32
+ %mul2979.2 = mul i32 %indvars107.2, %14
+ %add3181.2 = or disjoint i32 %mul2979.2, 1
+ %add32.2 = mul i32 %add3181.2, %14
+ %arrayidx34.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106.1
+ store i32 %add32.2, ptr %arrayidx34.2, align 8, !tbaa !4
+ %indvars.iv.next106.3 = add nuw nsw i64 %indvars.iv105, 4
+ %indvars107.3 = trunc i64 %indvars.iv.next106.3 to i32
+ %15 = trunc nuw nsw i64 %indvars.iv.next106.2 to i32
+ %mul2979.3 = mul i32 %indvars107.3, %15
+ %add3181.3 = or disjoint i32 %mul2979.3, 1
+ %add32.3 = mul i32 %add3181.3, %15
+ %arrayidx34.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106.2
+ store i32 %add32.3, ptr %arrayidx34.3, align 4, !tbaa !4
+ %niter115.next.3 = add i64 %niter115, 4
+ %niter115.ncmp.3 = icmp eq i64 %niter115.next.3, %unroll_iter114
+ br i1 %niter115.ncmp.3, label %for.cond.cleanup26.loopexit.unr-lcssa, label %for.body27, !llvm.loop !14
+
+if.else38: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ br i1 %cmp84, label %for.body45.preheader, label %for.cond.cleanup44
+
+for.body45.preheader: ; preds = %if.else38
+ %wide.trip.count97 = zext nneg i32 %len to i64
+ br label %for.body45
+
+for.cond.cleanup44: ; preds = %for.body45, %if.else38
+ tail call void @func2()
+ unreachable
+
+for.body45: ; preds = %for.body45.preheader, %for.body45
+ %indvars.iv93 = phi i64 [ 0, %for.body45.preheader ], [ %indvars.iv.next94, %for.body45 ]
+ %arrayidx47 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv93
+ %16 = load i32, ptr %arrayidx47, align 4, !tbaa !4
+ %call48 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %16)
+ %indvars.iv.next94 = add nuw nsw i64 %indvars.iv93, 1
+ %exitcond98.not = icmp eq i64 %indvars.iv.next94, %wide.trip.count97
+ br i1 %exitcond98.not, label %for.cond.cleanup44, label %for.body45, !llvm.loop !15
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readonly %argv) local_unnamed_addr #5 {
+entry:
+ %cmp = icmp slt i32 %argc, 2
+ br i1 %cmp, label %return, label %if.end
+
+if.end: ; preds = %entry
+ %arrayidx = getelementptr inbounds i8, ptr %argv, i64 8
+ %0 = load ptr, ptr %arrayidx, align 8, !tbaa !16
+ %call.i = tail call i64 @strtol(ptr nocapture noundef nonnull %0, ptr noundef null, i32 noundef signext 10) #4
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp2 = icmp eq i32 %1, 0
+ br i1 %cmp2, label %if.then3, label %return
+
+if.then3: ; preds = %if.end
+ %conv.i = trunc i64 %call.i to i32
+ %puts8 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %call5 = tail call signext i32 @func1(i32 noundef signext %conv.i)
+ unreachable
+
+return: ; preds = %if.end, %entry
+ %str.17.sink = phi ptr [ @str.19, %entry ], [ @str.17, %if.end ]
+ %retval.0 = phi i32 [ 1, %entry ], [ 0, %if.end ]
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) %str.17.sink)
+ ret i32 %retval.0
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn
+declare i64 @strtol(ptr noundef readonly, ptr nocapture noundef, i32 noundef signext) local_unnamed_addr #6
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { mustprogress nofree nounwind willreturn "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = distinct !{!8, !9}
+!9 = !{!"llvm.loop.unroll.disable"}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
+!13 = distinct !{!13, !9}
+!14 = distinct !{!14, !11}
+!15 = distinct !{!15, !11}
+!16 = !{!17, !17, i64 0}
+!17 = !{!"any pointer", !6, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll
index 2cb2b885ee985c..c104cb9fb894a6 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-02.ll
@@ -1,38 +1,29 @@
-; -mbackchain option
+; -mbackchain option.
; Test for Frame Pointer in first slot in jmp_buf.
-; Test assembly for nested setjmp for alloa.
-; This test case takes input from stdin for size of alloca
-; and produce the right result.
-; Frame Pointer in slot 1.
-; Return address in slot 2.
-; Backchain value in slot 3.
-; Stack Pointer in slot 4.
-; Clobber %r6-%r15, %f8-%f15.
+; Test assembly for store/load to/from for nested setjmp for alloca for
+; setjmp/longjmp respectively.
+; RUN: llc -O2 < %s | FileCheck %s
-; RUN: llc < %s | FileCheck %s
-
-
-; ModuleID = 'builtin-setjmp-longjmp-alloca-01.c'
-source_filename = "builtin-setjmp-longjmp-alloca-01.c"
+; ModuleID = 'builtin-setjmp-longjmp-alloca-02.c'
+source_filename = "builtin-setjmp-longjmp-alloca-02.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
target triple = "s390x-unknown-linux-gnu"
@buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
- at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
- at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
- at .str.8 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at len = dso_local local_unnamed_addr global i32 10, align 4
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
@str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
- at str.12 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
- at str.13 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
- at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
- at str.15 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
- at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
- at str.17 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
- at str.18 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
- at str.19 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
; Function Attrs: noinline noreturn nounwind
define dso_local void @func4() local_unnamed_addr #0 {
@@ -51,7 +42,22 @@ declare void @llvm.eh.sjlj.longjmp(ptr) #2
; Function Attrs: noinline noreturn nounwind
define dso_local void @func3() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+; Load Frame Pointer from slot 1.
+; Load return address from slot 2.
+; Load backchain value from slot 3.
+; Load stack pointer from slot 4.
+; Load literal pointer from slot 5.
+
+;CHECK: larl %r1, buf2
+;CHECK: lg %r2, 8(%r1)
+;CHECK: lg %r11, 0(%r1)
+;CHECK: lg %r13, 32(%r1)
+;CHECK: lg %r3, 16(%r1)
+;CHECK: lg %r15, 24(%r1)
+;CHECK: stg %r3, 0(%r15)
+;CHECK: br %r2
+
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
unreachable
}
@@ -59,31 +65,25 @@ entry:
; Function Attrs: noinline noreturn nounwind
define dso_local void @func2() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
unreachable
}
; Function Attrs: noreturn nounwind
-define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+define dso_local noundef signext i32 @func1(i32 noundef signext %len) local_unnamed_addr #3 {
entry:
- %len = alloca i32, align 4
- call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
- store i32 10, ptr %len, align 4, !tbaa !4
- %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
- %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
- %0 = load i32, ptr %len, align 4, !tbaa !4
- %conv = sext i32 %0 to i64
+ %conv = sext i32 %len to i64
%mul = shl nsw i64 %conv, 2
- %1 = alloca i8, i64 %mul, align 8
- %cmp82 = icmp sgt i32 %0, 0
- br i1 %cmp82, label %for.body.preheader, label %for.cond.cleanup
+ %0 = alloca i8, i64 %mul, align 8
+ %cmp84 = icmp sgt i32 %len, 0
+ br i1 %cmp84, label %for.body.preheader, label %for.cond.cleanup
for.body.preheader: ; preds = %entry
- %wide.trip.count = zext nneg i32 %0 to i64
+ %wide.trip.count = zext nneg i32 %len to i64
%xtraiter = and i64 %wide.trip.count, 3
- %2 = icmp ult i32 %0, 4
- br i1 %2, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
+ %1 = icmp ult i32 %len, 4
+ br i1 %1, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
for.body.preheader.new: ; preds = %for.body.preheader
%unroll_iter = and i64 %wide.trip.count, 2147483644
@@ -99,223 +99,215 @@ for.body.epil: ; preds = %for.cond.cleanup.lo
%epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
%indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
%indvars.epil = trunc i64 %indvars.iv.next.epil to i32
- %3 = trunc nuw nsw i64 %indvars.iv.epil to i32
- %add.epil = mul i32 %indvars.epil, %3
- %arrayidx.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.epil
+ %2 = trunc nuw nsw i64 %indvars.iv.epil to i32
+ %add.epil = mul i32 %indvars.epil, %2
+ %arrayidx.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.epil
store i32 %add.epil, ptr %arrayidx.epil, align 4, !tbaa !4
%epil.iter.next = add i64 %epil.iter, 1
%epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
-; CHECK: larl %r1, buf1
-; CHECK: lg %r2, 8(%r1)
-; CHECK: lg %r11, 0(%r1)
-; CHECK: lg %r13, 32(%r1)
-; CHECK: lg %r3, 16(%r1)
-; CHECK: stg %r3, 0(%r15)
-; CHECK: lg %r15, 24(%r1)
-; CHECK: br %r2
-
- %4 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
- %cmp4 = icmp eq i32 %4, 0
- br i1 %cmp4, label %if.then, label %if.else40
+; Store Frame Pointer in slot 1.
+; Store Return address in slot 2.
+; Store Stack Pointer in slot 4.
+
+; CHECK: larl %r1, buf2
+; CHECK: larl %r0, .LBB3_13
+; CHECK: stg %r0, 8(%r1)
+; CHECK: stg %r11, 0(%r1)
+; CHECK: stg %r15, 24(%r1)
+; CHECK: lg %r0, 0(%r15)
+; CHECK: stg %r0, 16(%r1)
+
+ %3 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %3, 0
+ br i1 %cmp3, label %if.then, label %if.else38
for.body: ; preds = %for.body, %for.body.preheader.new
%indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
%niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
%indvars.iv.next = or disjoint i64 %indvars.iv, 1
%indvars = trunc i64 %indvars.iv.next to i32
- %5 = trunc nuw nsw i64 %indvars.iv to i32
- %add = mul i32 %indvars, %5
- %arrayidx = getelementptr inbounds i32, ptr %1, i64 %indvars.iv
+ %4 = trunc nuw nsw i64 %indvars.iv to i32
+ %add = mul i32 %indvars, %4
+ %arrayidx = getelementptr inbounds i32, ptr %0, i64 %indvars.iv
store i32 %add, ptr %arrayidx, align 8, !tbaa !4
%indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
%indvars.1 = trunc i64 %indvars.iv.next.1 to i32
- %6 = trunc nuw nsw i64 %indvars.iv.next to i32
- %add.1 = mul i32 %indvars.1, %6
- %arrayidx.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next
+ %5 = trunc nuw nsw i64 %indvars.iv.next to i32
+ %add.1 = mul i32 %indvars.1, %5
+ %arrayidx.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next
store i32 %add.1, ptr %arrayidx.1, align 4, !tbaa !4
%indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
%indvars.2 = trunc i64 %indvars.iv.next.2 to i32
- %7 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
- %add.2 = mul i32 %indvars.2, %7
- %arrayidx.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.1
+ %6 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
+ %add.2 = mul i32 %indvars.2, %6
+ %arrayidx.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.1
store i32 %add.2, ptr %arrayidx.2, align 8, !tbaa !4
%indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
%indvars.3 = trunc i64 %indvars.iv.next.3 to i32
- %8 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
- %add.3 = mul i32 %indvars.3, %8
- %arrayidx.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next.2
+ %7 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
+ %add.3 = mul i32 %indvars.3, %7
+ %arrayidx.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.2
store i32 %add.3, ptr %arrayidx.3, align 4, !tbaa !4
%niter.next.3 = add i64 %niter, 4
%niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
if.then: ; preds = %for.cond.cleanup
- %puts75 = call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
- %9 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
- %cmp7 = icmp eq i32 %9, 0
- br i1 %cmp7, label %if.then9, label %if.else
-
-if.then9: ; preds = %if.then
- %puts80 = call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
- call void @func4()
+ %puts77 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %8 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %8, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
unreachable
if.else: ; preds = %if.then
- %puts76 = call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
- %10 = load i32, ptr %len, align 4, !tbaa !4
- %cmp1486 = icmp sgt i32 %10, 0
- br i1 %cmp1486, label %for.body17, label %for.cond.cleanup28
-
-for.cond25.preheader: ; preds = %for.body17
- %cmp2688 = icmp sgt i32 %13, 0
- br i1 %cmp2688, label %for.body29.preheader, label %for.cond.cleanup28
-
-for.body29.preheader: ; preds = %for.cond25.preheader
- %wide.trip.count104 = zext nneg i32 %13 to i64
- %xtraiter108 = and i64 %wide.trip.count104, 3
- %11 = icmp ult i32 %13, 4
- br i1 %11, label %for.cond.cleanup28.loopexit.unr-lcssa, label %for.body29.preheader.new
-
-for.body29.preheader.new: ; preds = %for.body29.preheader
- %unroll_iter111 = and i64 %wide.trip.count104, 2147483644
- br label %for.body29
-
-for.body17: ; preds = %if.else, %for.body17
- %indvars.iv96 = phi i64 [ %indvars.iv.next97, %for.body17 ], [ 0, %if.else ]
- %arrayidx19 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv96
- %12 = load i32, ptr %arrayidx19, align 4, !tbaa !4
- %call20 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %12)
- %indvars.iv.next97 = add nuw nsw i64 %indvars.iv96, 1
- %13 = load i32, ptr %len, align 4, !tbaa !4
- %14 = sext i32 %13 to i64
- %cmp14 = icmp slt i64 %indvars.iv.next97, %14
- br i1 %cmp14, label %for.body17, label %for.cond25.preheader, !llvm.loop !12
-
-for.cond.cleanup28.loopexit.unr-lcssa: ; preds = %for.body29, %for.body29.preheader
- %indvars.iv100.unr = phi i64 [ 0, %for.body29.preheader ], [ %indvars.iv.next101.3, %for.body29 ]
- %lcmp.mod110.not = icmp eq i64 %xtraiter108, 0
- br i1 %lcmp.mod110.not, label %for.cond.cleanup28, label %for.body29.epil
-
-for.body29.epil: ; preds = %for.cond.cleanup28.loopexit.unr-lcssa, %for.body29.epil
- %indvars.iv100.epil = phi i64 [ %indvars.iv.next101.epil, %for.body29.epil ], [ %indvars.iv100.unr, %for.cond.cleanup28.loopexit.unr-lcssa ]
- %epil.iter109 = phi i64 [ %epil.iter109.next, %for.body29.epil ], [ 0, %for.cond.cleanup28.loopexit.unr-lcssa ]
- %indvars.iv.next101.epil = add nuw nsw i64 %indvars.iv100.epil, 1
- %indvars102.epil = trunc i64 %indvars.iv.next101.epil to i32
- %15 = trunc nuw nsw i64 %indvars.iv100.epil to i32
- %mul3177.epil = mul i32 %indvars102.epil, %15
- %add3379.epil = add nuw nsw i32 %mul3177.epil, 1
- %add34.epil = mul i32 %add3379.epil, %15
- %arrayidx36.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv100.epil
- store i32 %add34.epil, ptr %arrayidx36.epil, align 4, !tbaa !4
- %epil.iter109.next = add i64 %epil.iter109, 1
- %epil.iter109.cmp.not = icmp eq i64 %epil.iter109.next, %xtraiter108
- br i1 %epil.iter109.cmp.not, label %for.cond.cleanup28, label %for.body29.epil, !llvm.loop !13
-
-for.cond.cleanup28: ; preds = %for.cond.cleanup28.loopexit.unr-lcssa, %for.body29.epil, %if.else, %for.cond25.preheader
- call void @func3()
+ %puts78 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ br i1 %cmp84, label %for.body15.preheader, label %for.cond.cleanup26
+
+for.body15.preheader: ; preds = %if.else
+ %wide.trip.count103 = zext nneg i32 %len to i64
+ br label %for.body15
+
+for.body27.preheader: ; preds = %for.body15
+ %xtraiter111 = and i64 %wide.trip.count103, 3
+ %9 = icmp ult i32 %len, 4
+ br i1 %9, label %for.cond.cleanup26.loopexit.unr-lcssa, label %for.body27.preheader.new
+
+for.body27.preheader.new: ; preds = %for.body27.preheader
+ %unroll_iter114 = and i64 %wide.trip.count103, 2147483644
+ br label %for.body27
+
+for.body15: ; preds = %for.body15.preheader, %for.body15
+ %indvars.iv99 = phi i64 [ 0, %for.body15.preheader ], [ %indvars.iv.next100, %for.body15 ]
+ %arrayidx17 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv99
+ %10 = load i32, ptr %arrayidx17, align 4, !tbaa !4
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %10)
+ %indvars.iv.next100 = add nuw nsw i64 %indvars.iv99, 1
+ %exitcond104.not = icmp eq i64 %indvars.iv.next100, %wide.trip.count103
+ br i1 %exitcond104.not, label %for.body27.preheader, label %for.body15, !llvm.loop !12
+
+for.cond.cleanup26.loopexit.unr-lcssa: ; preds = %for.body27, %for.body27.preheader
+ %indvars.iv105.unr = phi i64 [ 0, %for.body27.preheader ], [ %indvars.iv.next106.3, %for.body27 ]
+ %lcmp.mod113.not = icmp eq i64 %xtraiter111, 0
+ br i1 %lcmp.mod113.not, label %for.cond.cleanup26, label %for.body27.epil
+
+for.body27.epil: ; preds = %for.cond.cleanup26.loopexit.unr-lcssa, %for.body27.epil
+ %indvars.iv105.epil = phi i64 [ %indvars.iv.next106.epil, %for.body27.epil ], [ %indvars.iv105.unr, %for.cond.cleanup26.loopexit.unr-lcssa ]
+ %epil.iter112 = phi i64 [ %epil.iter112.next, %for.body27.epil ], [ 0, %for.cond.cleanup26.loopexit.unr-lcssa ]
+ %indvars.iv.next106.epil = add nuw nsw i64 %indvars.iv105.epil, 1
+ %indvars107.epil = trunc i64 %indvars.iv.next106.epil to i32
+ %11 = trunc nuw nsw i64 %indvars.iv105.epil to i32
+ %mul2979.epil = mul i32 %indvars107.epil, %11
+ %add3181.epil = add nuw nsw i32 %mul2979.epil, 1
+ %add32.epil = mul i32 %add3181.epil, %11
+ %arrayidx34.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv105.epil
+ store i32 %add32.epil, ptr %arrayidx34.epil, align 4, !tbaa !4
+ %epil.iter112.next = add i64 %epil.iter112, 1
+ %epil.iter112.cmp.not = icmp eq i64 %epil.iter112.next, %xtraiter111
+ br i1 %epil.iter112.cmp.not, label %for.cond.cleanup26, label %for.body27.epil, !llvm.loop !13
+
+for.cond.cleanup26: ; preds = %for.cond.cleanup26.loopexit.unr-lcssa, %for.body27.epil, %if.else
+ tail call void @func3()
unreachable
-for.body29: ; preds = %for.body29, %for.body29.preheader.new
- %indvars.iv100 = phi i64 [ 0, %for.body29.preheader.new ], [ %indvars.iv.next101.3, %for.body29 ]
- %niter112 = phi i64 [ 0, %for.body29.preheader.new ], [ %niter112.next.3, %for.body29 ]
- %indvars.iv.next101 = or disjoint i64 %indvars.iv100, 1
- %indvars102 = trunc i64 %indvars.iv.next101 to i32
- %16 = trunc nuw nsw i64 %indvars.iv100 to i32
- %mul3177 = mul i32 %indvars102, %16
- %add3379 = or disjoint i32 %mul3177, 1
- %add34 = mul i32 %add3379, %16
- %arrayidx36 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv100
- store i32 %add34, ptr %arrayidx36, align 8, !tbaa !4
- %indvars.iv.next101.1 = or disjoint i64 %indvars.iv100, 2
- %indvars102.1 = trunc i64 %indvars.iv.next101.1 to i32
- %17 = trunc nuw nsw i64 %indvars.iv.next101 to i32
- %mul3177.1 = mul i32 %indvars102.1, %17
- %add3379.1 = or disjoint i32 %mul3177.1, 1
- %add34.1 = mul i32 %add3379.1, %17
- %arrayidx36.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101
- store i32 %add34.1, ptr %arrayidx36.1, align 4, !tbaa !4
- %indvars.iv.next101.2 = or disjoint i64 %indvars.iv100, 3
- %indvars102.2 = trunc i64 %indvars.iv.next101.2 to i32
- %18 = trunc nuw nsw i64 %indvars.iv.next101.1 to i32
- %mul3177.2 = mul i32 %indvars102.2, %18
- %add3379.2 = or disjoint i32 %mul3177.2, 1
- %add34.2 = mul i32 %add3379.2, %18
- %arrayidx36.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101.1
- store i32 %add34.2, ptr %arrayidx36.2, align 8, !tbaa !4
- %indvars.iv.next101.3 = add nuw nsw i64 %indvars.iv100, 4
- %indvars102.3 = trunc i64 %indvars.iv.next101.3 to i32
- %19 = trunc nuw nsw i64 %indvars.iv.next101.2 to i32
- %mul3177.3 = mul i32 %indvars102.3, %19
- %add3379.3 = or disjoint i32 %mul3177.3, 1
- %add34.3 = mul i32 %add3379.3, %19
- %arrayidx36.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next101.2
- store i32 %add34.3, ptr %arrayidx36.3, align 4, !tbaa !4
- %niter112.next.3 = add i64 %niter112, 4
- %niter112.ncmp.3 = icmp eq i64 %niter112.next.3, %unroll_iter111
- br i1 %niter112.ncmp.3, label %for.cond.cleanup28.loopexit.unr-lcssa, label %for.body29, !llvm.loop !14
-
-if.else40: ; preds = %for.cond.cleanup
- %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
- %20 = load i32, ptr %len, align 4, !tbaa !4
- %cmp4484 = icmp sgt i32 %20, 0
- br i1 %cmp4484, label %for.body47, label %for.cond.cleanup46
-
-for.cond.cleanup46: ; preds = %for.body47, %if.else40
- call void @func2()
- unreachable
+for.body27: ; preds = %for.body27, %for.body27.preheader.new
+ %indvars.iv105 = phi i64 [ 0, %for.body27.preheader.new ], [ %indvars.iv.next106.3, %for.body27 ]
+ %niter115 = phi i64 [ 0, %for.body27.preheader.new ], [ %niter115.next.3, %for.body27 ]
+ %indvars.iv.next106 = or disjoint i64 %indvars.iv105, 1
+ %indvars107 = trunc i64 %indvars.iv.next106 to i32
+ %12 = trunc nuw nsw i64 %indvars.iv105 to i32
+ %mul2979 = mul i32 %indvars107, %12
+ %add3181 = or disjoint i32 %mul2979, 1
+ %add32 = mul i32 %add3181, %12
+ %arrayidx34 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv105
+ store i32 %add32, ptr %arrayidx34, align 8, !tbaa !4
+ %indvars.iv.next106.1 = or disjoint i64 %indvars.iv105, 2
+ %indvars107.1 = trunc i64 %indvars.iv.next106.1 to i32
+ %13 = trunc nuw nsw i64 %indvars.iv.next106 to i32
+ %mul2979.1 = mul i32 %indvars107.1, %13
+ %add3181.1 = or disjoint i32 %mul2979.1, 1
+ %add32.1 = mul i32 %add3181.1, %13
+ %arrayidx34.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106
+ store i32 %add32.1, ptr %arrayidx34.1, align 4, !tbaa !4
+ %indvars.iv.next106.2 = or disjoint i64 %indvars.iv105, 3
+ %indvars107.2 = trunc i64 %indvars.iv.next106.2 to i32
+ %14 = trunc nuw nsw i64 %indvars.iv.next106.1 to i32
+ %mul2979.2 = mul i32 %indvars107.2, %14
+ %add3181.2 = or disjoint i32 %mul2979.2, 1
+ %add32.2 = mul i32 %add3181.2, %14
+ %arrayidx34.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106.1
+ store i32 %add32.2, ptr %arrayidx34.2, align 8, !tbaa !4
+ %indvars.iv.next106.3 = add nuw nsw i64 %indvars.iv105, 4
+ %indvars107.3 = trunc i64 %indvars.iv.next106.3 to i32
+ %15 = trunc nuw nsw i64 %indvars.iv.next106.2 to i32
+ %mul2979.3 = mul i32 %indvars107.3, %15
+ %add3181.3 = or disjoint i32 %mul2979.3, 1
+ %add32.3 = mul i32 %add3181.3, %15
+ %arrayidx34.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next106.2
+ store i32 %add32.3, ptr %arrayidx34.3, align 4, !tbaa !4
+ %niter115.next.3 = add i64 %niter115, 4
+ %niter115.ncmp.3 = icmp eq i64 %niter115.next.3, %unroll_iter114
+ br i1 %niter115.ncmp.3, label %for.cond.cleanup26.loopexit.unr-lcssa, label %for.body27, !llvm.loop !14
+
+if.else38: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ br i1 %cmp84, label %for.body45.preheader, label %for.cond.cleanup44
-for.body47: ; preds = %if.else40, %for.body47
- %indvars.iv92 = phi i64 [ %indvars.iv.next93, %for.body47 ], [ 0, %if.else40 ]
- %arrayidx49 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv92
- %21 = load i32, ptr %arrayidx49, align 4, !tbaa !4
- %call50 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %21)
- %indvars.iv.next93 = add nuw nsw i64 %indvars.iv92, 1
- %22 = load i32, ptr %len, align 4, !tbaa !4
- %23 = sext i32 %22 to i64
- %cmp44 = icmp slt i64 %indvars.iv.next93, %23
- br i1 %cmp44, label %for.body47, label %for.cond.cleanup46, !llvm.loop !15
-}
+for.body45.preheader: ; preds = %if.else38
+ %wide.trip.count97 = zext nneg i32 %len to i64
+ br label %for.body45
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
-declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
+for.cond.cleanup44: ; preds = %for.body45, %if.else38
+ tail call void @func2()
+ unreachable
-; Function Attrs: nofree nounwind
-declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+for.body45: ; preds = %for.body45.preheader, %for.body45
+ %indvars.iv93 = phi i64 [ 0, %for.body45.preheader ], [ %indvars.iv.next94, %for.body45 ]
+ %arrayidx47 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv93
+ %16 = load i32, ptr %arrayidx47, align 4, !tbaa !4
+ %call48 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %16)
+ %indvars.iv.next94 = add nuw nsw i64 %indvars.iv93, 1
+ %exitcond98.not = icmp eq i64 %indvars.iv.next94, %wide.trip.count97
+ br i1 %exitcond98.not, label %for.cond.cleanup44, label %for.body45, !llvm.loop !15
+}
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
; Function Attrs: nounwind
-define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
entry:
%0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
%cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
- %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
- %call1 = tail call signext i32 @func1()
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %1 = load i32, ptr @len, align 4, !tbaa !4
+ %call1 = tail call signext i32 @func1(i32 noundef signext %1)
unreachable
if.else: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
ret i32 0
}
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #2 = { noreturn nounwind }
attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-attributes #5 = { nounwind }
-attributes #6 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #7 = { nofree nounwind }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -323,7 +315,7 @@ attributes #7 = { nofree nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
!4 = !{!5, !5, i64 0}
!5 = !{!"int", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-03.ll
index 3d787de19e3737..2cb2bbe51338f7 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-03.ll
@@ -1,14 +1,10 @@
-; -mbackchain option
+; -mbackchain option.
+; This test case produces right result when alloca len is not local variable.
+; Test output of setjmp/longjmp with nested setjmp for alloca
; Test for Frame Pointer in first slot in jmp_buf.
-; Test assembly for nested setjmp for alloa with switch statement.
-; This test case takes input from stdin for size of alloca
-; and produce the right result.
-; Frame Pointer in slot 1.
-; Return address in slot 2.
-; Backchain value in slot 3.
-; Stack Pointer in slot 4.
-; RUN: llc < %s | FileCheck %s
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
; ModuleID = 'builtin-setjmp-longjmp-alloca-03.c'
source_filename = "builtin-setjmp-longjmp-alloca-03.c"
@@ -18,23 +14,22 @@ target triple = "s390x-unknown-linux-gnu"
@buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
- at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
- at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
- at .str.13 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at len = dso_local local_unnamed_addr global i32 10, align 4
+ at .str.11 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
@str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
- at str.17 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
- at str.18 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
- at str.19 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
- at str.20 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
- at str.21 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
- at str.27 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
- at str.28 = private unnamed_addr constant [8 x i8] c"case 4:\00", align 1
- at str.29 = private unnamed_addr constant [8 x i8] c"case 3:\00", align 1
- at str.30 = private unnamed_addr constant [8 x i8] c"case 2:\00", align 1
- at str.31 = private unnamed_addr constant [8 x i8] c"case 1:\00", align 1
- at str.32 = private unnamed_addr constant [8 x i8] c"case 0:\00", align 1
- at str.33 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
- at str.34 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.15 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.16 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.18 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.25 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.26 = private unnamed_addr constant [8 x i8] c"case 4:\00", align 1
+ at str.27 = private unnamed_addr constant [8 x i8] c"case 3:\00", align 1
+ at str.28 = private unnamed_addr constant [8 x i8] c"case 2:\00", align 1
+ at str.29 = private unnamed_addr constant [8 x i8] c"case 1:\00", align 1
+ at str.30 = private unnamed_addr constant [8 x i8] c"case 0:\00", align 1
+ at str.31 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.32 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
; Function Attrs: noinline noreturn nounwind
define dso_local void @func4() local_unnamed_addr #0 {
@@ -53,7 +48,7 @@ declare void @llvm.eh.sjlj.longjmp(ptr) #2
; Function Attrs: noinline noreturn nounwind
define dso_local void @func3() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
unreachable
}
@@ -61,7 +56,7 @@ entry:
; Function Attrs: noinline noreturn nounwind
define dso_local void @func2() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
unreachable
}
@@ -69,17 +64,12 @@ entry:
; Function Attrs: noreturn nounwind
define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
entry:
- %len = alloca i32, align 4
- call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
- store i32 10, ptr %len, align 4, !tbaa !4
- %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
- %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
- %0 = load i32, ptr %len, align 4, !tbaa !4
+ %0 = load i32, ptr @len, align 4, !tbaa !4
%conv = sext i32 %0 to i64
%mul = shl nsw i64 %conv, 2
%1 = alloca i8, i64 %mul, align 8
- %cmp350 = icmp sgt i32 %0, 0
- br i1 %cmp350, label %for.body.preheader, label %for.cond.cleanup
+ %cmp348 = icmp sgt i32 %0, 0
+ br i1 %cmp348, label %for.body.preheader, label %for.cond.cleanup
for.body.preheader: ; preds = %entry
%wide.trip.count = zext nneg i32 %0 to i64
@@ -110,9 +100,36 @@ for.body.epil: ; preds = %for.cond.cleanup.lo
br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !8
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
- %4 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
- %cmp4 = icmp eq i32 %4, 0
- br i1 %cmp4, label %if.then, label %if.else202
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: case 0:
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 4
+; CHECK: arr: 10
+; CHECK: arr: 18
+; CHECK: arr: 28
+; CHECK: arr: 40
+; CHECK: arr: 54
+; CHECK: arr: 70
+; CHECK: arr: 88
+; CHECK: arr: 108
+; CHECK: case 0:
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 5
+; CHECK: arr: 26
+; CHECK: arr: 99
+; CHECK: arr: 284
+; CHECK: arr: 665
+; CHECK: arr: 1350
+; CHECK: arr: 2471
+; CHECK: arr: 4184
+; CHECK: arr: 6669
+
+ %4 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %4, 0
+ br i1 %cmp3, label %if.then, label %if.else200
for.body: ; preds = %for.body, %for.body.preheader.new
%indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
@@ -146,857 +163,841 @@ for.body: ; preds = %for.body, %for.body
br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !10
if.then: ; preds = %for.cond.cleanup
- %puts307 = call i32 @puts(ptr nonnull dereferenceable(1) @str.20)
- %9 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
- %cmp7 = icmp eq i32 %9, 0
- br i1 %cmp7, label %if.then9, label %if.else
-
-if.then9: ; preds = %if.then
- %puts324 = call i32 @puts(ptr nonnull dereferenceable(1) @str.27)
- %10 = load i32, ptr %len, align 4, !tbaa !4
+ %puts305 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %9 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %9, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts322 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.25)
+ %10 = load i32, ptr @len, align 4, !tbaa !4
%rem = srem i32 %10, 5
switch i32 %rem, label %sw.epilog [
i32 0, label %sw.bb
- i32 1, label %sw.bb26
- i32 2, label %sw.bb45
- i32 3, label %sw.bb63
- i32 4, label %sw.bb79
+ i32 1, label %sw.bb24
+ i32 2, label %sw.bb43
+ i32 3, label %sw.bb61
+ i32 4, label %sw.bb77
]
-sw.bb: ; preds = %if.then9
- %puts339 = call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
- %11 = load i32, ptr %len, align 4, !tbaa !4
- %cmp14374 = icmp sgt i32 %11, 0
- br i1 %cmp14374, label %for.body17.preheader, label %sw.epilog
+sw.bb: ; preds = %if.then7
+ %puts337 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
+ %11 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp12372 = icmp sgt i32 %11, 0
+ br i1 %cmp12372, label %for.body15.preheader, label %sw.epilog
-for.body17.preheader: ; preds = %sw.bb
- %wide.trip.count460 = zext nneg i32 %11 to i64
- %xtraiter534 = and i64 %wide.trip.count460, 3
+for.body15.preheader: ; preds = %sw.bb
+ %wide.trip.count458 = zext nneg i32 %11 to i64
+ %xtraiter532 = and i64 %wide.trip.count458, 3
%12 = icmp ult i32 %11, 4
- br i1 %12, label %sw.epilog.loopexit.unr-lcssa, label %for.body17.preheader.new
-
-for.body17.preheader.new: ; preds = %for.body17.preheader
- %unroll_iter537 = and i64 %wide.trip.count460, 2147483644
- br label %for.body17
-
-for.body17: ; preds = %for.body17, %for.body17.preheader.new
- %indvars.iv455 = phi i64 [ 0, %for.body17.preheader.new ], [ %indvars.iv.next456.3, %for.body17 ]
- %niter538 = phi i64 [ 0, %for.body17.preheader.new ], [ %niter538.next.3, %for.body17 ]
- %indvars459 = trunc i64 %indvars.iv455 to i32
- %mul19340 = or disjoint i32 %indvars459, 3
- %add20 = mul i32 %mul19340, %indvars459
- %arrayidx22 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv455
- store i32 %add20, ptr %arrayidx22, align 8, !tbaa !4
- %indvars.iv.next456 = or disjoint i64 %indvars.iv455, 1
- %indvars459.1 = trunc i64 %indvars.iv.next456 to i32
- %mul19340.1 = add nuw i32 %indvars459.1, 3
- %add20.1 = mul i32 %mul19340.1, %indvars459.1
- %arrayidx22.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456
- store i32 %add20.1, ptr %arrayidx22.1, align 4, !tbaa !4
- %indvars.iv.next456.1 = or disjoint i64 %indvars.iv455, 2
- %indvars459.2 = trunc i64 %indvars.iv.next456.1 to i32
- %mul19340.2 = add nuw i32 %indvars459.2, 3
- %add20.2 = mul i32 %mul19340.2, %indvars459.2
- %arrayidx22.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456.1
- store i32 %add20.2, ptr %arrayidx22.2, align 8, !tbaa !4
- %indvars.iv.next456.2 = or disjoint i64 %indvars.iv455, 3
- %indvars459.3 = trunc i64 %indvars.iv.next456.2 to i32
- %mul19340.3 = add nuw i32 %indvars459.3, 3
- %add20.3 = mul i32 %mul19340.3, %indvars459.3
- %arrayidx22.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next456.2
- store i32 %add20.3, ptr %arrayidx22.3, align 4, !tbaa !4
- %indvars.iv.next456.3 = add nuw nsw i64 %indvars.iv455, 4
- %niter538.next.3 = add i64 %niter538, 4
- %niter538.ncmp.3 = icmp eq i64 %niter538.next.3, %unroll_iter537
- br i1 %niter538.ncmp.3, label %sw.epilog.loopexit.unr-lcssa, label %for.body17, !llvm.loop !12
-
-sw.bb26: ; preds = %if.then9
- %puts335 = call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
- %13 = load i32, ptr %len, align 4, !tbaa !4
- %cmp30372 = icmp sgt i32 %13, 0
- br i1 %cmp30372, label %for.body33.preheader, label %sw.epilog
-
-for.body33.preheader: ; preds = %sw.bb26
- %wide.trip.count453 = zext nneg i32 %13 to i64
- %xtraiter529 = and i64 %wide.trip.count453, 3
+ br i1 %12, label %sw.epilog.loopexit.unr-lcssa, label %for.body15.preheader.new
+
+for.body15.preheader.new: ; preds = %for.body15.preheader
+ %unroll_iter535 = and i64 %wide.trip.count458, 2147483644
+ br label %for.body15
+
+for.body15: ; preds = %for.body15, %for.body15.preheader.new
+ %indvars.iv453 = phi i64 [ 0, %for.body15.preheader.new ], [ %indvars.iv.next454.3, %for.body15 ]
+ %niter536 = phi i64 [ 0, %for.body15.preheader.new ], [ %niter536.next.3, %for.body15 ]
+ %indvars457 = trunc i64 %indvars.iv453 to i32
+ %mul17338 = or disjoint i32 %indvars457, 3
+ %add18 = mul i32 %mul17338, %indvars457
+ %arrayidx20 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv453
+ store i32 %add18, ptr %arrayidx20, align 8, !tbaa !4
+ %indvars.iv.next454 = or disjoint i64 %indvars.iv453, 1
+ %indvars457.1 = trunc i64 %indvars.iv.next454 to i32
+ %mul17338.1 = add nuw i32 %indvars457.1, 3
+ %add18.1 = mul i32 %mul17338.1, %indvars457.1
+ %arrayidx20.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next454
+ store i32 %add18.1, ptr %arrayidx20.1, align 4, !tbaa !4
+ %indvars.iv.next454.1 = or disjoint i64 %indvars.iv453, 2
+ %indvars457.2 = trunc i64 %indvars.iv.next454.1 to i32
+ %mul17338.2 = add nuw i32 %indvars457.2, 3
+ %add18.2 = mul i32 %mul17338.2, %indvars457.2
+ %arrayidx20.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next454.1
+ store i32 %add18.2, ptr %arrayidx20.2, align 8, !tbaa !4
+ %indvars.iv.next454.2 = or disjoint i64 %indvars.iv453, 3
+ %indvars457.3 = trunc i64 %indvars.iv.next454.2 to i32
+ %mul17338.3 = add nuw i32 %indvars457.3, 3
+ %add18.3 = mul i32 %mul17338.3, %indvars457.3
+ %arrayidx20.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next454.2
+ store i32 %add18.3, ptr %arrayidx20.3, align 4, !tbaa !4
+ %indvars.iv.next454.3 = add nuw nsw i64 %indvars.iv453, 4
+ %niter536.next.3 = add i64 %niter536, 4
+ %niter536.ncmp.3 = icmp eq i64 %niter536.next.3, %unroll_iter535
+ br i1 %niter536.ncmp.3, label %sw.epilog.loopexit.unr-lcssa, label %for.body15, !llvm.loop !12
+
+sw.bb24: ; preds = %if.then7
+ %puts333 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
+ %13 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp28370 = icmp sgt i32 %13, 0
+ br i1 %cmp28370, label %for.body31.preheader, label %sw.epilog
+
+for.body31.preheader: ; preds = %sw.bb24
+ %wide.trip.count451 = zext nneg i32 %13 to i64
+ %xtraiter527 = and i64 %wide.trip.count451, 3
%14 = icmp ult i32 %13, 4
- br i1 %14, label %sw.epilog.loopexit480.unr-lcssa, label %for.body33.preheader.new
-
-for.body33.preheader.new: ; preds = %for.body33.preheader
- %unroll_iter532 = and i64 %wide.trip.count453, 2147483644
- br label %for.body33
-
-for.body33: ; preds = %for.body33, %for.body33.preheader.new
- %indvars.iv449 = phi i64 [ 0, %for.body33.preheader.new ], [ %indvars.iv.next450.3, %for.body33 ]
- %niter533 = phi i64 [ 0, %for.body33.preheader.new ], [ %niter533.next.3, %for.body33 ]
- %indvars.iv.next450 = or disjoint i64 %indvars.iv449, 1
- %indvars451 = trunc i64 %indvars.iv.next450 to i32
- %15 = trunc nuw nsw i64 %indvars.iv449 to i32
- %mul35336 = mul i32 %indvars451, %15
- %add37338 = or disjoint i32 %mul35336, 3
- %add39 = mul i32 %add37338, %15
- %arrayidx41 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv449
- store i32 %add39, ptr %arrayidx41, align 8, !tbaa !4
- %indvars.iv.next450.1 = or disjoint i64 %indvars.iv449, 2
- %indvars451.1 = trunc i64 %indvars.iv.next450.1 to i32
- %16 = trunc nuw nsw i64 %indvars.iv.next450 to i32
- %mul35336.1 = mul i32 %indvars451.1, %16
- %add37338.1 = add i32 %mul35336.1, 3
- %add39.1 = mul i32 %add37338.1, %16
- %arrayidx41.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450
- store i32 %add39.1, ptr %arrayidx41.1, align 4, !tbaa !4
- %indvars.iv.next450.2 = or disjoint i64 %indvars.iv449, 3
- %indvars451.2 = trunc i64 %indvars.iv.next450.2 to i32
- %17 = trunc nuw nsw i64 %indvars.iv.next450.1 to i32
- %mul35336.2 = mul i32 %indvars451.2, %17
- %add37338.2 = add i32 %mul35336.2, 3
- %add39.2 = mul i32 %add37338.2, %17
- %arrayidx41.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450.1
- store i32 %add39.2, ptr %arrayidx41.2, align 8, !tbaa !4
- %indvars.iv.next450.3 = add nuw nsw i64 %indvars.iv449, 4
- %indvars451.3 = trunc i64 %indvars.iv.next450.3 to i32
- %18 = trunc nuw nsw i64 %indvars.iv.next450.2 to i32
- %mul35336.3 = mul i32 %indvars451.3, %18
- %add37338.3 = or disjoint i32 %mul35336.3, 3
- %add39.3 = mul i32 %add37338.3, %18
- %arrayidx41.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next450.2
- store i32 %add39.3, ptr %arrayidx41.3, align 4, !tbaa !4
- %niter533.next.3 = add i64 %niter533, 4
- %niter533.ncmp.3 = icmp eq i64 %niter533.next.3, %unroll_iter532
- br i1 %niter533.ncmp.3, label %sw.epilog.loopexit480.unr-lcssa, label %for.body33, !llvm.loop !13
-
-sw.bb45: ; preds = %if.then9
- %puts331 = call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
- %19 = load i32, ptr %len, align 4, !tbaa !4
- %cmp49370 = icmp sgt i32 %19, 0
- br i1 %cmp49370, label %for.body52.preheader, label %sw.epilog
-
-for.body52.preheader: ; preds = %sw.bb45
- %wide.trip.count447 = zext nneg i32 %19 to i64
- %xtraiter524 = and i64 %wide.trip.count447, 3
+ br i1 %14, label %sw.epilog.loopexit478.unr-lcssa, label %for.body31.preheader.new
+
+for.body31.preheader.new: ; preds = %for.body31.preheader
+ %unroll_iter530 = and i64 %wide.trip.count451, 2147483644
+ br label %for.body31
+
+for.body31: ; preds = %for.body31, %for.body31.preheader.new
+ %indvars.iv447 = phi i64 [ 0, %for.body31.preheader.new ], [ %indvars.iv.next448.3, %for.body31 ]
+ %niter531 = phi i64 [ 0, %for.body31.preheader.new ], [ %niter531.next.3, %for.body31 ]
+ %indvars.iv.next448 = or disjoint i64 %indvars.iv447, 1
+ %indvars449 = trunc i64 %indvars.iv.next448 to i32
+ %15 = trunc nuw nsw i64 %indvars.iv447 to i32
+ %mul33334 = mul i32 %indvars449, %15
+ %add35336 = or disjoint i32 %mul33334, 3
+ %add37 = mul i32 %add35336, %15
+ %arrayidx39 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv447
+ store i32 %add37, ptr %arrayidx39, align 8, !tbaa !4
+ %indvars.iv.next448.1 = or disjoint i64 %indvars.iv447, 2
+ %indvars449.1 = trunc i64 %indvars.iv.next448.1 to i32
+ %16 = trunc nuw nsw i64 %indvars.iv.next448 to i32
+ %mul33334.1 = mul i32 %indvars449.1, %16
+ %add35336.1 = add i32 %mul33334.1, 3
+ %add37.1 = mul i32 %add35336.1, %16
+ %arrayidx39.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next448
+ store i32 %add37.1, ptr %arrayidx39.1, align 4, !tbaa !4
+ %indvars.iv.next448.2 = or disjoint i64 %indvars.iv447, 3
+ %indvars449.2 = trunc i64 %indvars.iv.next448.2 to i32
+ %17 = trunc nuw nsw i64 %indvars.iv.next448.1 to i32
+ %mul33334.2 = mul i32 %indvars449.2, %17
+ %add35336.2 = add i32 %mul33334.2, 3
+ %add37.2 = mul i32 %add35336.2, %17
+ %arrayidx39.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next448.1
+ store i32 %add37.2, ptr %arrayidx39.2, align 8, !tbaa !4
+ %indvars.iv.next448.3 = add nuw nsw i64 %indvars.iv447, 4
+ %indvars449.3 = trunc i64 %indvars.iv.next448.3 to i32
+ %18 = trunc nuw nsw i64 %indvars.iv.next448.2 to i32
+ %mul33334.3 = mul i32 %indvars449.3, %18
+ %add35336.3 = or disjoint i32 %mul33334.3, 3
+ %add37.3 = mul i32 %add35336.3, %18
+ %arrayidx39.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next448.2
+ store i32 %add37.3, ptr %arrayidx39.3, align 4, !tbaa !4
+ %niter531.next.3 = add i64 %niter531, 4
+ %niter531.ncmp.3 = icmp eq i64 %niter531.next.3, %unroll_iter530
+ br i1 %niter531.ncmp.3, label %sw.epilog.loopexit478.unr-lcssa, label %for.body31, !llvm.loop !13
+
+sw.bb43: ; preds = %if.then7
+ %puts329 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
+ %19 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp47368 = icmp sgt i32 %19, 0
+ br i1 %cmp47368, label %for.body50.preheader, label %sw.epilog
+
+for.body50.preheader: ; preds = %sw.bb43
+ %wide.trip.count445 = zext nneg i32 %19 to i64
+ %xtraiter522 = and i64 %wide.trip.count445, 3
%20 = icmp ult i32 %19, 4
- br i1 %20, label %sw.epilog.loopexit481.unr-lcssa, label %for.body52.preheader.new
-
-for.body52.preheader.new: ; preds = %for.body52.preheader
- %unroll_iter527 = and i64 %wide.trip.count447, 2147483644
- br label %for.body52
-
-for.body52: ; preds = %for.body52, %for.body52.preheader.new
- %indvars.iv442 = phi i64 [ 0, %for.body52.preheader.new ], [ %indvars.iv.next443.3, %for.body52 ]
- %niter528 = phi i64 [ 0, %for.body52.preheader.new ], [ %niter528.next.3, %for.body52 ]
- %indvars446 = trunc i64 %indvars.iv442 to i32
- %i47.0333 = add nsw i32 %indvars446, -1
- %mul54332 = mul i32 %i47.0333, %indvars446
- %sub334 = or disjoint i32 %mul54332, 3
- %add57 = mul i32 %sub334, %indvars446
- %arrayidx59 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv442
- store i32 %add57, ptr %arrayidx59, align 8, !tbaa !4
- %indvars.iv.next443 = or disjoint i64 %indvars.iv442, 1
- %indvars446.1 = trunc i64 %indvars.iv.next443 to i32
- %i47.0333.1 = add nsw i32 %indvars446.1, -1
- %mul54332.1 = mul i32 %i47.0333.1, %indvars446.1
- %sub334.1 = or disjoint i32 %mul54332.1, 3
- %add57.1 = mul i32 %sub334.1, %indvars446.1
- %arrayidx59.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443
- store i32 %add57.1, ptr %arrayidx59.1, align 4, !tbaa !4
- %indvars.iv.next443.1 = or disjoint i64 %indvars.iv442, 2
- %indvars446.2 = trunc i64 %indvars.iv.next443.1 to i32
- %i47.0333.2 = add nsw i32 %indvars446.2, -1
- %mul54332.2 = mul i32 %i47.0333.2, %indvars446.2
- %sub334.2 = add i32 %mul54332.2, 3
- %add57.2 = mul i32 %sub334.2, %indvars446.2
- %arrayidx59.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443.1
- store i32 %add57.2, ptr %arrayidx59.2, align 8, !tbaa !4
- %indvars.iv.next443.2 = or disjoint i64 %indvars.iv442, 3
- %indvars446.3 = trunc i64 %indvars.iv.next443.2 to i32
- %i47.0333.3 = add nsw i32 %indvars446.3, -1
- %mul54332.3 = mul i32 %i47.0333.3, %indvars446.3
- %sub334.3 = add i32 %mul54332.3, 3
- %add57.3 = mul i32 %sub334.3, %indvars446.3
- %arrayidx59.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next443.2
- store i32 %add57.3, ptr %arrayidx59.3, align 4, !tbaa !4
- %indvars.iv.next443.3 = add nuw nsw i64 %indvars.iv442, 4
- %niter528.next.3 = add i64 %niter528, 4
- %niter528.ncmp.3 = icmp eq i64 %niter528.next.3, %unroll_iter527
- br i1 %niter528.ncmp.3, label %sw.epilog.loopexit481.unr-lcssa, label %for.body52, !llvm.loop !14
-
-sw.bb63: ; preds = %if.then9
- %puts329 = call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
- %21 = load i32, ptr %len, align 4, !tbaa !4
- %cmp67368 = icmp sgt i32 %21, 0
- br i1 %cmp67368, label %for.body70.preheader, label %sw.epilog
-
-for.body70.preheader: ; preds = %sw.bb63
- %wide.trip.count440 = zext nneg i32 %21 to i64
- %xtraiter519 = and i64 %wide.trip.count440, 3
+ br i1 %20, label %sw.epilog.loopexit479.unr-lcssa, label %for.body50.preheader.new
+
+for.body50.preheader.new: ; preds = %for.body50.preheader
+ %unroll_iter525 = and i64 %wide.trip.count445, 2147483644
+ br label %for.body50
+
+for.body50: ; preds = %for.body50, %for.body50.preheader.new
+ %indvars.iv440 = phi i64 [ 0, %for.body50.preheader.new ], [ %indvars.iv.next441.3, %for.body50 ]
+ %niter526 = phi i64 [ 0, %for.body50.preheader.new ], [ %niter526.next.3, %for.body50 ]
+ %indvars444 = trunc i64 %indvars.iv440 to i32
+ %i45.0331 = add nsw i32 %indvars444, -1
+ %mul52330 = mul i32 %i45.0331, %indvars444
+ %sub332 = or disjoint i32 %mul52330, 3
+ %add55 = mul i32 %sub332, %indvars444
+ %arrayidx57 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv440
+ store i32 %add55, ptr %arrayidx57, align 8, !tbaa !4
+ %indvars.iv.next441 = or disjoint i64 %indvars.iv440, 1
+ %indvars444.1 = trunc i64 %indvars.iv.next441 to i32
+ %i45.0331.1 = add nsw i32 %indvars444.1, -1
+ %mul52330.1 = mul i32 %i45.0331.1, %indvars444.1
+ %sub332.1 = or disjoint i32 %mul52330.1, 3
+ %add55.1 = mul i32 %sub332.1, %indvars444.1
+ %arrayidx57.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next441
+ store i32 %add55.1, ptr %arrayidx57.1, align 4, !tbaa !4
+ %indvars.iv.next441.1 = or disjoint i64 %indvars.iv440, 2
+ %indvars444.2 = trunc i64 %indvars.iv.next441.1 to i32
+ %i45.0331.2 = add nsw i32 %indvars444.2, -1
+ %mul52330.2 = mul i32 %i45.0331.2, %indvars444.2
+ %sub332.2 = add i32 %mul52330.2, 3
+ %add55.2 = mul i32 %sub332.2, %indvars444.2
+ %arrayidx57.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next441.1
+ store i32 %add55.2, ptr %arrayidx57.2, align 8, !tbaa !4
+ %indvars.iv.next441.2 = or disjoint i64 %indvars.iv440, 3
+ %indvars444.3 = trunc i64 %indvars.iv.next441.2 to i32
+ %i45.0331.3 = add nsw i32 %indvars444.3, -1
+ %mul52330.3 = mul i32 %i45.0331.3, %indvars444.3
+ %sub332.3 = add i32 %mul52330.3, 3
+ %add55.3 = mul i32 %sub332.3, %indvars444.3
+ %arrayidx57.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next441.2
+ store i32 %add55.3, ptr %arrayidx57.3, align 4, !tbaa !4
+ %indvars.iv.next441.3 = add nuw nsw i64 %indvars.iv440, 4
+ %niter526.next.3 = add i64 %niter526, 4
+ %niter526.ncmp.3 = icmp eq i64 %niter526.next.3, %unroll_iter525
+ br i1 %niter526.ncmp.3, label %sw.epilog.loopexit479.unr-lcssa, label %for.body50, !llvm.loop !14
+
+sw.bb61: ; preds = %if.then7
+ %puts327 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.27)
+ %21 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp65366 = icmp sgt i32 %21, 0
+ br i1 %cmp65366, label %for.body68.preheader, label %sw.epilog
+
+for.body68.preheader: ; preds = %sw.bb61
+ %wide.trip.count438 = zext nneg i32 %21 to i64
+ %xtraiter517 = and i64 %wide.trip.count438, 3
%22 = icmp ult i32 %21, 4
- br i1 %22, label %sw.epilog.loopexit482.unr-lcssa, label %for.body70.preheader.new
-
-for.body70.preheader.new: ; preds = %for.body70.preheader
- %unroll_iter522 = and i64 %wide.trip.count440, 2147483644
- br label %for.body70
-
-for.body70: ; preds = %for.body70, %for.body70.preheader.new
- %indvars.iv436 = phi i64 [ 0, %for.body70.preheader.new ], [ %indvars.iv.next437.3, %for.body70 ]
- %niter523 = phi i64 [ 0, %for.body70.preheader.new ], [ %niter523.next.3, %for.body70 ]
- %indvars.iv.next437 = or disjoint i64 %indvars.iv436, 1
- %indvars438 = trunc i64 %indvars.iv.next437 to i32
- %23 = trunc nuw nsw i64 %indvars.iv436 to i32
- %add72 = mul i32 %indvars438, %23
- %add73 = or disjoint i32 %add72, 3
- %arrayidx75 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv436
- store i32 %add73, ptr %arrayidx75, align 8, !tbaa !4
- %indvars.iv.next437.1 = or disjoint i64 %indvars.iv436, 2
- %indvars438.1 = trunc i64 %indvars.iv.next437.1 to i32
- %24 = trunc nuw nsw i64 %indvars.iv.next437 to i32
- %add72.1 = mul i32 %indvars438.1, %24
- %add73.1 = add nsw i32 %add72.1, 3
- %arrayidx75.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437
- store i32 %add73.1, ptr %arrayidx75.1, align 4, !tbaa !4
- %indvars.iv.next437.2 = or disjoint i64 %indvars.iv436, 3
- %indvars438.2 = trunc i64 %indvars.iv.next437.2 to i32
- %25 = trunc nuw nsw i64 %indvars.iv.next437.1 to i32
- %add72.2 = mul i32 %indvars438.2, %25
- %add73.2 = add nsw i32 %add72.2, 3
- %arrayidx75.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437.1
- store i32 %add73.2, ptr %arrayidx75.2, align 8, !tbaa !4
- %indvars.iv.next437.3 = add nuw nsw i64 %indvars.iv436, 4
- %indvars438.3 = trunc i64 %indvars.iv.next437.3 to i32
- %26 = trunc nuw nsw i64 %indvars.iv.next437.2 to i32
- %add72.3 = mul i32 %indvars438.3, %26
- %add73.3 = or disjoint i32 %add72.3, 3
- %arrayidx75.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next437.2
- store i32 %add73.3, ptr %arrayidx75.3, align 4, !tbaa !4
- %niter523.next.3 = add i64 %niter523, 4
- %niter523.ncmp.3 = icmp eq i64 %niter523.next.3, %unroll_iter522
- br i1 %niter523.ncmp.3, label %sw.epilog.loopexit482.unr-lcssa, label %for.body70, !llvm.loop !15
-
-sw.bb79: ; preds = %if.then9
- %puts325 = call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
- %27 = load i32, ptr %len, align 4, !tbaa !4
- %cmp83366 = icmp sgt i32 %27, 0
- br i1 %cmp83366, label %for.body86.preheader, label %sw.epilog
-
-for.body86.preheader: ; preds = %sw.bb79
- %wide.trip.count434 = zext nneg i32 %27 to i64
- %xtraiter514 = and i64 %wide.trip.count434, 3
+ br i1 %22, label %sw.epilog.loopexit480.unr-lcssa, label %for.body68.preheader.new
+
+for.body68.preheader.new: ; preds = %for.body68.preheader
+ %unroll_iter520 = and i64 %wide.trip.count438, 2147483644
+ br label %for.body68
+
+for.body68: ; preds = %for.body68, %for.body68.preheader.new
+ %indvars.iv434 = phi i64 [ 0, %for.body68.preheader.new ], [ %indvars.iv.next435.3, %for.body68 ]
+ %niter521 = phi i64 [ 0, %for.body68.preheader.new ], [ %niter521.next.3, %for.body68 ]
+ %indvars.iv.next435 = or disjoint i64 %indvars.iv434, 1
+ %indvars436 = trunc i64 %indvars.iv.next435 to i32
+ %23 = trunc nuw nsw i64 %indvars.iv434 to i32
+ %add70 = mul i32 %indvars436, %23
+ %add71 = or disjoint i32 %add70, 3
+ %arrayidx73 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv434
+ store i32 %add71, ptr %arrayidx73, align 8, !tbaa !4
+ %indvars.iv.next435.1 = or disjoint i64 %indvars.iv434, 2
+ %indvars436.1 = trunc i64 %indvars.iv.next435.1 to i32
+ %24 = trunc nuw nsw i64 %indvars.iv.next435 to i32
+ %add70.1 = mul i32 %indvars436.1, %24
+ %add71.1 = add nsw i32 %add70.1, 3
+ %arrayidx73.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next435
+ store i32 %add71.1, ptr %arrayidx73.1, align 4, !tbaa !4
+ %indvars.iv.next435.2 = or disjoint i64 %indvars.iv434, 3
+ %indvars436.2 = trunc i64 %indvars.iv.next435.2 to i32
+ %25 = trunc nuw nsw i64 %indvars.iv.next435.1 to i32
+ %add70.2 = mul i32 %indvars436.2, %25
+ %add71.2 = add nsw i32 %add70.2, 3
+ %arrayidx73.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next435.1
+ store i32 %add71.2, ptr %arrayidx73.2, align 8, !tbaa !4
+ %indvars.iv.next435.3 = add nuw nsw i64 %indvars.iv434, 4
+ %indvars436.3 = trunc i64 %indvars.iv.next435.3 to i32
+ %26 = trunc nuw nsw i64 %indvars.iv.next435.2 to i32
+ %add70.3 = mul i32 %indvars436.3, %26
+ %add71.3 = or disjoint i32 %add70.3, 3
+ %arrayidx73.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next435.2
+ store i32 %add71.3, ptr %arrayidx73.3, align 4, !tbaa !4
+ %niter521.next.3 = add i64 %niter521, 4
+ %niter521.ncmp.3 = icmp eq i64 %niter521.next.3, %unroll_iter520
+ br i1 %niter521.ncmp.3, label %sw.epilog.loopexit480.unr-lcssa, label %for.body68, !llvm.loop !15
+
+sw.bb77: ; preds = %if.then7
+ %puts323 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.26)
+ %27 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp81364 = icmp sgt i32 %27, 0
+ br i1 %cmp81364, label %for.body84.preheader, label %sw.epilog
+
+for.body84.preheader: ; preds = %sw.bb77
+ %wide.trip.count432 = zext nneg i32 %27 to i64
+ %xtraiter512 = and i64 %wide.trip.count432, 3
%28 = icmp ult i32 %27, 4
- br i1 %28, label %sw.epilog.loopexit483.unr-lcssa, label %for.body86.preheader.new
-
-for.body86.preheader.new: ; preds = %for.body86.preheader
- %unroll_iter517 = and i64 %wide.trip.count434, 2147483644
- br label %for.body86
-
-for.body86: ; preds = %for.body86, %for.body86.preheader.new
- %indvars.iv428 = phi i64 [ 0, %for.body86.preheader.new ], [ %indvars.iv.next429.3, %for.body86 ]
- %niter518 = phi i64 [ 0, %for.body86.preheader.new ], [ %niter518.next.3, %for.body86 ]
- %indvars433 = trunc i64 %indvars.iv428 to i32
- %mul87 = mul nuw nsw i32 %indvars433, %indvars433
- %mul88327 = or disjoint i32 %mul87, 1
- %mul89326 = mul i32 %mul88327, %indvars433
- %add91328 = or disjoint i32 %mul89326, 3
- %add93 = mul i32 %add91328, %indvars433
- %arrayidx95 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv428
- store i32 %add93, ptr %arrayidx95, align 8, !tbaa !4
- %indvars.iv.next429 = or disjoint i64 %indvars.iv428, 1
- %indvars433.1 = trunc i64 %indvars.iv.next429 to i32
- %mul87.1 = mul nuw nsw i32 %indvars433.1, %indvars433.1
- %mul88327.1 = add nuw nsw i32 %mul87.1, 1
- %mul89326.1 = mul i32 %mul88327.1, %indvars433.1
- %add91328.1 = add i32 %mul89326.1, 3
- %add93.1 = mul i32 %add91328.1, %indvars433.1
- %arrayidx95.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429
- store i32 %add93.1, ptr %arrayidx95.1, align 4, !tbaa !4
- %indvars.iv.next429.1 = or disjoint i64 %indvars.iv428, 2
- %indvars433.2 = trunc i64 %indvars.iv.next429.1 to i32
- %mul87.2 = mul nuw nsw i32 %indvars433.2, %indvars433.2
- %mul88327.2 = or disjoint i32 %mul87.2, 1
- %mul89326.2 = mul i32 %mul88327.2, %indvars433.2
- %add91328.2 = add i32 %mul89326.2, 3
- %add93.2 = mul i32 %add91328.2, %indvars433.2
- %arrayidx95.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429.1
- store i32 %add93.2, ptr %arrayidx95.2, align 8, !tbaa !4
- %indvars.iv.next429.2 = or disjoint i64 %indvars.iv428, 3
- %indvars433.3 = trunc i64 %indvars.iv.next429.2 to i32
- %mul87.3 = mul nuw nsw i32 %indvars433.3, %indvars433.3
- %mul88327.3 = add nuw nsw i32 %mul87.3, 1
- %mul89326.3 = mul i32 %mul88327.3, %indvars433.3
- %add91328.3 = add i32 %mul89326.3, 3
- %add93.3 = mul i32 %add91328.3, %indvars433.3
- %arrayidx95.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next429.2
- store i32 %add93.3, ptr %arrayidx95.3, align 4, !tbaa !4
- %indvars.iv.next429.3 = add nuw nsw i64 %indvars.iv428, 4
- %niter518.next.3 = add i64 %niter518, 4
- %niter518.ncmp.3 = icmp eq i64 %niter518.next.3, %unroll_iter517
- br i1 %niter518.ncmp.3, label %sw.epilog.loopexit483.unr-lcssa, label %for.body86, !llvm.loop !16
-
-sw.epilog.loopexit.unr-lcssa: ; preds = %for.body17, %for.body17.preheader
- %indvars.iv455.unr = phi i64 [ 0, %for.body17.preheader ], [ %indvars.iv.next456.3, %for.body17 ]
- %lcmp.mod536.not = icmp eq i64 %xtraiter534, 0
- br i1 %lcmp.mod536.not, label %sw.epilog, label %for.body17.epil
-
-for.body17.epil: ; preds = %sw.epilog.loopexit.unr-lcssa, %for.body17.epil
- %indvars.iv455.epil = phi i64 [ %indvars.iv.next456.epil, %for.body17.epil ], [ %indvars.iv455.unr, %sw.epilog.loopexit.unr-lcssa ]
- %epil.iter535 = phi i64 [ %epil.iter535.next, %for.body17.epil ], [ 0, %sw.epilog.loopexit.unr-lcssa ]
- %indvars459.epil = trunc i64 %indvars.iv455.epil to i32
- %mul19340.epil = add nuw i32 %indvars459.epil, 3
- %add20.epil = mul i32 %mul19340.epil, %indvars459.epil
- %arrayidx22.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv455.epil
- store i32 %add20.epil, ptr %arrayidx22.epil, align 4, !tbaa !4
- %indvars.iv.next456.epil = add nuw nsw i64 %indvars.iv455.epil, 1
- %epil.iter535.next = add i64 %epil.iter535, 1
- %epil.iter535.cmp.not = icmp eq i64 %epil.iter535.next, %xtraiter534
- br i1 %epil.iter535.cmp.not, label %sw.epilog, label %for.body17.epil, !llvm.loop !17
-
-sw.epilog.loopexit480.unr-lcssa: ; preds = %for.body33, %for.body33.preheader
- %indvars.iv449.unr = phi i64 [ 0, %for.body33.preheader ], [ %indvars.iv.next450.3, %for.body33 ]
- %lcmp.mod531.not = icmp eq i64 %xtraiter529, 0
- br i1 %lcmp.mod531.not, label %sw.epilog, label %for.body33.epil
-
-for.body33.epil: ; preds = %sw.epilog.loopexit480.unr-lcssa, %for.body33.epil
- %indvars.iv449.epil = phi i64 [ %indvars.iv.next450.epil, %for.body33.epil ], [ %indvars.iv449.unr, %sw.epilog.loopexit480.unr-lcssa ]
- %epil.iter530 = phi i64 [ %epil.iter530.next, %for.body33.epil ], [ 0, %sw.epilog.loopexit480.unr-lcssa ]
- %indvars.iv.next450.epil = add nuw nsw i64 %indvars.iv449.epil, 1
- %indvars451.epil = trunc i64 %indvars.iv.next450.epil to i32
- %29 = trunc nuw nsw i64 %indvars.iv449.epil to i32
- %mul35336.epil = mul i32 %indvars451.epil, %29
- %add37338.epil = add i32 %mul35336.epil, 3
- %add39.epil = mul i32 %add37338.epil, %29
- %arrayidx41.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv449.epil
- store i32 %add39.epil, ptr %arrayidx41.epil, align 4, !tbaa !4
- %epil.iter530.next = add i64 %epil.iter530, 1
- %epil.iter530.cmp.not = icmp eq i64 %epil.iter530.next, %xtraiter529
- br i1 %epil.iter530.cmp.not, label %sw.epilog, label %for.body33.epil, !llvm.loop !18
-
-sw.epilog.loopexit481.unr-lcssa: ; preds = %for.body52, %for.body52.preheader
- %indvars.iv442.unr = phi i64 [ 0, %for.body52.preheader ], [ %indvars.iv.next443.3, %for.body52 ]
- %lcmp.mod526.not = icmp eq i64 %xtraiter524, 0
- br i1 %lcmp.mod526.not, label %sw.epilog, label %for.body52.epil
-
-for.body52.epil: ; preds = %sw.epilog.loopexit481.unr-lcssa, %for.body52.epil
- %indvars.iv442.epil = phi i64 [ %indvars.iv.next443.epil, %for.body52.epil ], [ %indvars.iv442.unr, %sw.epilog.loopexit481.unr-lcssa ]
- %epil.iter525 = phi i64 [ %epil.iter525.next, %for.body52.epil ], [ 0, %sw.epilog.loopexit481.unr-lcssa ]
- %indvars446.epil = trunc i64 %indvars.iv442.epil to i32
- %i47.0333.epil = add nsw i32 %indvars446.epil, -1
- %mul54332.epil = mul i32 %i47.0333.epil, %indvars446.epil
- %sub334.epil = add i32 %mul54332.epil, 3
- %add57.epil = mul i32 %sub334.epil, %indvars446.epil
- %arrayidx59.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv442.epil
- store i32 %add57.epil, ptr %arrayidx59.epil, align 4, !tbaa !4
- %indvars.iv.next443.epil = add nuw nsw i64 %indvars.iv442.epil, 1
- %epil.iter525.next = add i64 %epil.iter525, 1
- %epil.iter525.cmp.not = icmp eq i64 %epil.iter525.next, %xtraiter524
- br i1 %epil.iter525.cmp.not, label %sw.epilog, label %for.body52.epil, !llvm.loop !19
-
-sw.epilog.loopexit482.unr-lcssa: ; preds = %for.body70, %for.body70.preheader
- %indvars.iv436.unr = phi i64 [ 0, %for.body70.preheader ], [ %indvars.iv.next437.3, %for.body70 ]
- %lcmp.mod521.not = icmp eq i64 %xtraiter519, 0
- br i1 %lcmp.mod521.not, label %sw.epilog, label %for.body70.epil
-
-for.body70.epil: ; preds = %sw.epilog.loopexit482.unr-lcssa, %for.body70.epil
- %indvars.iv436.epil = phi i64 [ %indvars.iv.next437.epil, %for.body70.epil ], [ %indvars.iv436.unr, %sw.epilog.loopexit482.unr-lcssa ]
- %epil.iter520 = phi i64 [ %epil.iter520.next, %for.body70.epil ], [ 0, %sw.epilog.loopexit482.unr-lcssa ]
- %indvars.iv.next437.epil = add nuw nsw i64 %indvars.iv436.epil, 1
- %indvars438.epil = trunc i64 %indvars.iv.next437.epil to i32
- %30 = trunc nuw nsw i64 %indvars.iv436.epil to i32
- %add72.epil = mul i32 %indvars438.epil, %30
- %add73.epil = add nsw i32 %add72.epil, 3
- %arrayidx75.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv436.epil
- store i32 %add73.epil, ptr %arrayidx75.epil, align 4, !tbaa !4
- %epil.iter520.next = add i64 %epil.iter520, 1
- %epil.iter520.cmp.not = icmp eq i64 %epil.iter520.next, %xtraiter519
- br i1 %epil.iter520.cmp.not, label %sw.epilog, label %for.body70.epil, !llvm.loop !20
-
-sw.epilog.loopexit483.unr-lcssa: ; preds = %for.body86, %for.body86.preheader
- %indvars.iv428.unr = phi i64 [ 0, %for.body86.preheader ], [ %indvars.iv.next429.3, %for.body86 ]
- %lcmp.mod516.not = icmp eq i64 %xtraiter514, 0
- br i1 %lcmp.mod516.not, label %sw.epilog, label %for.body86.epil
-
-for.body86.epil: ; preds = %sw.epilog.loopexit483.unr-lcssa, %for.body86.epil
- %indvars.iv428.epil = phi i64 [ %indvars.iv.next429.epil, %for.body86.epil ], [ %indvars.iv428.unr, %sw.epilog.loopexit483.unr-lcssa ]
- %epil.iter515 = phi i64 [ %epil.iter515.next, %for.body86.epil ], [ 0, %sw.epilog.loopexit483.unr-lcssa ]
- %indvars433.epil = trunc i64 %indvars.iv428.epil to i32
- %mul87.epil = mul nuw nsw i32 %indvars433.epil, %indvars433.epil
- %mul88327.epil = add nuw i32 %mul87.epil, 1
- %mul89326.epil = mul i32 %mul88327.epil, %indvars433.epil
- %add91328.epil = add i32 %mul89326.epil, 3
- %add93.epil = mul i32 %add91328.epil, %indvars433.epil
- %arrayidx95.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv428.epil
- store i32 %add93.epil, ptr %arrayidx95.epil, align 4, !tbaa !4
- %indvars.iv.next429.epil = add nuw nsw i64 %indvars.iv428.epil, 1
- %epil.iter515.next = add i64 %epil.iter515, 1
- %epil.iter515.cmp.not = icmp eq i64 %epil.iter515.next, %xtraiter514
- br i1 %epil.iter515.cmp.not, label %sw.epilog, label %for.body86.epil, !llvm.loop !21
-
-sw.epilog: ; preds = %sw.epilog.loopexit483.unr-lcssa, %for.body86.epil, %sw.epilog.loopexit482.unr-lcssa, %for.body70.epil, %sw.epilog.loopexit481.unr-lcssa, %for.body52.epil, %sw.epilog.loopexit480.unr-lcssa, %for.body33.epil, %sw.epilog.loopexit.unr-lcssa, %for.body17.epil, %sw.bb79, %sw.bb63, %sw.bb45, %sw.bb26, %sw.bb, %if.then9
- call void @func4()
+ br i1 %28, label %sw.epilog.loopexit481.unr-lcssa, label %for.body84.preheader.new
+
+for.body84.preheader.new: ; preds = %for.body84.preheader
+ %unroll_iter515 = and i64 %wide.trip.count432, 2147483644
+ br label %for.body84
+
+for.body84: ; preds = %for.body84, %for.body84.preheader.new
+ %indvars.iv426 = phi i64 [ 0, %for.body84.preheader.new ], [ %indvars.iv.next427.3, %for.body84 ]
+ %niter516 = phi i64 [ 0, %for.body84.preheader.new ], [ %niter516.next.3, %for.body84 ]
+ %indvars431 = trunc i64 %indvars.iv426 to i32
+ %mul85 = mul nuw nsw i32 %indvars431, %indvars431
+ %mul86325 = or disjoint i32 %mul85, 1
+ %mul87324 = mul i32 %mul86325, %indvars431
+ %add89326 = or disjoint i32 %mul87324, 3
+ %add91 = mul i32 %add89326, %indvars431
+ %arrayidx93 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv426
+ store i32 %add91, ptr %arrayidx93, align 8, !tbaa !4
+ %indvars.iv.next427 = or disjoint i64 %indvars.iv426, 1
+ %indvars431.1 = trunc i64 %indvars.iv.next427 to i32
+ %mul85.1 = mul nuw nsw i32 %indvars431.1, %indvars431.1
+ %mul86325.1 = add nuw nsw i32 %mul85.1, 1
+ %mul87324.1 = mul i32 %mul86325.1, %indvars431.1
+ %add89326.1 = add i32 %mul87324.1, 3
+ %add91.1 = mul i32 %add89326.1, %indvars431.1
+ %arrayidx93.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next427
+ store i32 %add91.1, ptr %arrayidx93.1, align 4, !tbaa !4
+ %indvars.iv.next427.1 = or disjoint i64 %indvars.iv426, 2
+ %indvars431.2 = trunc i64 %indvars.iv.next427.1 to i32
+ %mul85.2 = mul nuw nsw i32 %indvars431.2, %indvars431.2
+ %mul86325.2 = or disjoint i32 %mul85.2, 1
+ %mul87324.2 = mul i32 %mul86325.2, %indvars431.2
+ %add89326.2 = add i32 %mul87324.2, 3
+ %add91.2 = mul i32 %add89326.2, %indvars431.2
+ %arrayidx93.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next427.1
+ store i32 %add91.2, ptr %arrayidx93.2, align 8, !tbaa !4
+ %indvars.iv.next427.2 = or disjoint i64 %indvars.iv426, 3
+ %indvars431.3 = trunc i64 %indvars.iv.next427.2 to i32
+ %mul85.3 = mul nuw nsw i32 %indvars431.3, %indvars431.3
+ %mul86325.3 = add nuw nsw i32 %mul85.3, 1
+ %mul87324.3 = mul i32 %mul86325.3, %indvars431.3
+ %add89326.3 = add i32 %mul87324.3, 3
+ %add91.3 = mul i32 %add89326.3, %indvars431.3
+ %arrayidx93.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next427.2
+ store i32 %add91.3, ptr %arrayidx93.3, align 4, !tbaa !4
+ %indvars.iv.next427.3 = add nuw nsw i64 %indvars.iv426, 4
+ %niter516.next.3 = add i64 %niter516, 4
+ %niter516.ncmp.3 = icmp eq i64 %niter516.next.3, %unroll_iter515
+ br i1 %niter516.ncmp.3, label %sw.epilog.loopexit481.unr-lcssa, label %for.body84, !llvm.loop !16
+
+sw.epilog.loopexit.unr-lcssa: ; preds = %for.body15, %for.body15.preheader
+ %indvars.iv453.unr = phi i64 [ 0, %for.body15.preheader ], [ %indvars.iv.next454.3, %for.body15 ]
+ %lcmp.mod534.not = icmp eq i64 %xtraiter532, 0
+ br i1 %lcmp.mod534.not, label %sw.epilog, label %for.body15.epil
+
+for.body15.epil: ; preds = %sw.epilog.loopexit.unr-lcssa, %for.body15.epil
+ %indvars.iv453.epil = phi i64 [ %indvars.iv.next454.epil, %for.body15.epil ], [ %indvars.iv453.unr, %sw.epilog.loopexit.unr-lcssa ]
+ %epil.iter533 = phi i64 [ %epil.iter533.next, %for.body15.epil ], [ 0, %sw.epilog.loopexit.unr-lcssa ]
+ %indvars457.epil = trunc i64 %indvars.iv453.epil to i32
+ %mul17338.epil = add nuw i32 %indvars457.epil, 3
+ %add18.epil = mul i32 %mul17338.epil, %indvars457.epil
+ %arrayidx20.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv453.epil
+ store i32 %add18.epil, ptr %arrayidx20.epil, align 4, !tbaa !4
+ %indvars.iv.next454.epil = add nuw nsw i64 %indvars.iv453.epil, 1
+ %epil.iter533.next = add i64 %epil.iter533, 1
+ %epil.iter533.cmp.not = icmp eq i64 %epil.iter533.next, %xtraiter532
+ br i1 %epil.iter533.cmp.not, label %sw.epilog, label %for.body15.epil, !llvm.loop !17
+
+sw.epilog.loopexit478.unr-lcssa: ; preds = %for.body31, %for.body31.preheader
+ %indvars.iv447.unr = phi i64 [ 0, %for.body31.preheader ], [ %indvars.iv.next448.3, %for.body31 ]
+ %lcmp.mod529.not = icmp eq i64 %xtraiter527, 0
+ br i1 %lcmp.mod529.not, label %sw.epilog, label %for.body31.epil
+
+for.body31.epil: ; preds = %sw.epilog.loopexit478.unr-lcssa, %for.body31.epil
+ %indvars.iv447.epil = phi i64 [ %indvars.iv.next448.epil, %for.body31.epil ], [ %indvars.iv447.unr, %sw.epilog.loopexit478.unr-lcssa ]
+ %epil.iter528 = phi i64 [ %epil.iter528.next, %for.body31.epil ], [ 0, %sw.epilog.loopexit478.unr-lcssa ]
+ %indvars.iv.next448.epil = add nuw nsw i64 %indvars.iv447.epil, 1
+ %indvars449.epil = trunc i64 %indvars.iv.next448.epil to i32
+ %29 = trunc nuw nsw i64 %indvars.iv447.epil to i32
+ %mul33334.epil = mul i32 %indvars449.epil, %29
+ %add35336.epil = add i32 %mul33334.epil, 3
+ %add37.epil = mul i32 %add35336.epil, %29
+ %arrayidx39.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv447.epil
+ store i32 %add37.epil, ptr %arrayidx39.epil, align 4, !tbaa !4
+ %epil.iter528.next = add i64 %epil.iter528, 1
+ %epil.iter528.cmp.not = icmp eq i64 %epil.iter528.next, %xtraiter527
+ br i1 %epil.iter528.cmp.not, label %sw.epilog, label %for.body31.epil, !llvm.loop !18
+
+sw.epilog.loopexit479.unr-lcssa: ; preds = %for.body50, %for.body50.preheader
+ %indvars.iv440.unr = phi i64 [ 0, %for.body50.preheader ], [ %indvars.iv.next441.3, %for.body50 ]
+ %lcmp.mod524.not = icmp eq i64 %xtraiter522, 0
+ br i1 %lcmp.mod524.not, label %sw.epilog, label %for.body50.epil
+
+for.body50.epil: ; preds = %sw.epilog.loopexit479.unr-lcssa, %for.body50.epil
+ %indvars.iv440.epil = phi i64 [ %indvars.iv.next441.epil, %for.body50.epil ], [ %indvars.iv440.unr, %sw.epilog.loopexit479.unr-lcssa ]
+ %epil.iter523 = phi i64 [ %epil.iter523.next, %for.body50.epil ], [ 0, %sw.epilog.loopexit479.unr-lcssa ]
+ %indvars444.epil = trunc i64 %indvars.iv440.epil to i32
+ %i45.0331.epil = add nsw i32 %indvars444.epil, -1
+ %mul52330.epil = mul i32 %i45.0331.epil, %indvars444.epil
+ %sub332.epil = add i32 %mul52330.epil, 3
+ %add55.epil = mul i32 %sub332.epil, %indvars444.epil
+ %arrayidx57.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv440.epil
+ store i32 %add55.epil, ptr %arrayidx57.epil, align 4, !tbaa !4
+ %indvars.iv.next441.epil = add nuw nsw i64 %indvars.iv440.epil, 1
+ %epil.iter523.next = add i64 %epil.iter523, 1
+ %epil.iter523.cmp.not = icmp eq i64 %epil.iter523.next, %xtraiter522
+ br i1 %epil.iter523.cmp.not, label %sw.epilog, label %for.body50.epil, !llvm.loop !19
+
+sw.epilog.loopexit480.unr-lcssa: ; preds = %for.body68, %for.body68.preheader
+ %indvars.iv434.unr = phi i64 [ 0, %for.body68.preheader ], [ %indvars.iv.next435.3, %for.body68 ]
+ %lcmp.mod519.not = icmp eq i64 %xtraiter517, 0
+ br i1 %lcmp.mod519.not, label %sw.epilog, label %for.body68.epil
+
+for.body68.epil: ; preds = %sw.epilog.loopexit480.unr-lcssa, %for.body68.epil
+ %indvars.iv434.epil = phi i64 [ %indvars.iv.next435.epil, %for.body68.epil ], [ %indvars.iv434.unr, %sw.epilog.loopexit480.unr-lcssa ]
+ %epil.iter518 = phi i64 [ %epil.iter518.next, %for.body68.epil ], [ 0, %sw.epilog.loopexit480.unr-lcssa ]
+ %indvars.iv.next435.epil = add nuw nsw i64 %indvars.iv434.epil, 1
+ %indvars436.epil = trunc i64 %indvars.iv.next435.epil to i32
+ %30 = trunc nuw nsw i64 %indvars.iv434.epil to i32
+ %add70.epil = mul i32 %indvars436.epil, %30
+ %add71.epil = add nsw i32 %add70.epil, 3
+ %arrayidx73.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv434.epil
+ store i32 %add71.epil, ptr %arrayidx73.epil, align 4, !tbaa !4
+ %epil.iter518.next = add i64 %epil.iter518, 1
+ %epil.iter518.cmp.not = icmp eq i64 %epil.iter518.next, %xtraiter517
+ br i1 %epil.iter518.cmp.not, label %sw.epilog, label %for.body68.epil, !llvm.loop !20
+
+sw.epilog.loopexit481.unr-lcssa: ; preds = %for.body84, %for.body84.preheader
+ %indvars.iv426.unr = phi i64 [ 0, %for.body84.preheader ], [ %indvars.iv.next427.3, %for.body84 ]
+ %lcmp.mod514.not = icmp eq i64 %xtraiter512, 0
+ br i1 %lcmp.mod514.not, label %sw.epilog, label %for.body84.epil
+
+for.body84.epil: ; preds = %sw.epilog.loopexit481.unr-lcssa, %for.body84.epil
+ %indvars.iv426.epil = phi i64 [ %indvars.iv.next427.epil, %for.body84.epil ], [ %indvars.iv426.unr, %sw.epilog.loopexit481.unr-lcssa ]
+ %epil.iter513 = phi i64 [ %epil.iter513.next, %for.body84.epil ], [ 0, %sw.epilog.loopexit481.unr-lcssa ]
+ %indvars431.epil = trunc i64 %indvars.iv426.epil to i32
+ %mul85.epil = mul nuw nsw i32 %indvars431.epil, %indvars431.epil
+ %mul86325.epil = add nuw i32 %mul85.epil, 1
+ %mul87324.epil = mul i32 %mul86325.epil, %indvars431.epil
+ %add89326.epil = add i32 %mul87324.epil, 3
+ %add91.epil = mul i32 %add89326.epil, %indvars431.epil
+ %arrayidx93.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv426.epil
+ store i32 %add91.epil, ptr %arrayidx93.epil, align 4, !tbaa !4
+ %indvars.iv.next427.epil = add nuw nsw i64 %indvars.iv426.epil, 1
+ %epil.iter513.next = add i64 %epil.iter513, 1
+ %epil.iter513.cmp.not = icmp eq i64 %epil.iter513.next, %xtraiter512
+ br i1 %epil.iter513.cmp.not, label %sw.epilog, label %for.body84.epil, !llvm.loop !21
+
+sw.epilog: ; preds = %sw.epilog.loopexit481.unr-lcssa, %for.body84.epil, %sw.epilog.loopexit480.unr-lcssa, %for.body68.epil, %sw.epilog.loopexit479.unr-lcssa, %for.body50.epil, %sw.epilog.loopexit478.unr-lcssa, %for.body31.epil, %sw.epilog.loopexit.unr-lcssa, %for.body15.epil, %sw.bb77, %sw.bb61, %sw.bb43, %sw.bb24, %sw.bb, %if.then7
+ tail call void @func4()
unreachable
if.else: ; preds = %if.then
- %puts308 = call i32 @puts(ptr nonnull dereferenceable(1) @str.21)
- %31 = load i32, ptr %len, align 4, !tbaa !4
- %cmp102354 = icmp sgt i32 %31, 0
- br i1 %cmp102354, label %for.body105, label %for.cond.cleanup104
-
-for.cond.cleanup104: ; preds = %for.body105, %if.else
- %.lcssa = phi i32 [ %31, %if.else ], [ %33, %for.body105 ]
- %rem112 = srem i32 %.lcssa, 5
- switch i32 %rem112, label %sw.epilog201 [
- i32 0, label %sw.bb113
- i32 1, label %sw.bb133
- i32 2, label %sw.bb149
- i32 3, label %sw.bb166
- i32 4, label %sw.bb185
+ %puts306 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %31 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp100352 = icmp sgt i32 %31, 0
+ br i1 %cmp100352, label %for.body103, label %for.cond.cleanup102
+
+for.cond.cleanup102: ; preds = %for.body103, %if.else
+ %.lcssa = phi i32 [ %31, %if.else ], [ %33, %for.body103 ]
+ %rem110 = srem i32 %.lcssa, 5
+ switch i32 %rem110, label %sw.epilog199 [
+ i32 0, label %sw.bb111
+ i32 1, label %sw.bb131
+ i32 2, label %sw.bb147
+ i32 3, label %sw.bb164
+ i32 4, label %sw.bb183
]
-for.body105: ; preds = %if.else, %for.body105
- %indvars.iv390 = phi i64 [ %indvars.iv.next391, %for.body105 ], [ 0, %if.else ]
- %arrayidx107 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv390
- %32 = load i32, ptr %arrayidx107, align 4, !tbaa !4
- %call108 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %32)
- %indvars.iv.next391 = add nuw nsw i64 %indvars.iv390, 1
- %33 = load i32, ptr %len, align 4, !tbaa !4
+for.body103: ; preds = %if.else, %for.body103
+ %indvars.iv388 = phi i64 [ %indvars.iv.next389, %for.body103 ], [ 0, %if.else ]
+ %arrayidx105 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv388
+ %32 = load i32, ptr %arrayidx105, align 4, !tbaa !4
+ %call106 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %32)
+ %indvars.iv.next389 = add nuw nsw i64 %indvars.iv388, 1
+ %33 = load i32, ptr @len, align 4, !tbaa !4
%34 = sext i32 %33 to i64
- %cmp102 = icmp slt i64 %indvars.iv.next391, %34
- br i1 %cmp102, label %for.body105, label %for.cond.cleanup104, !llvm.loop !22
-
-sw.bb113: ; preds = %for.cond.cleanup104
- %puts320 = call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
- %35 = load i32, ptr %len, align 4, !tbaa !4
- %cmp117364 = icmp sgt i32 %35, 0
- br i1 %cmp117364, label %for.body120.preheader, label %sw.epilog201
-
-for.body120.preheader: ; preds = %sw.bb113
- %wide.trip.count426 = zext nneg i32 %35 to i64
- %xtraiter509 = and i64 %wide.trip.count426, 3
+ %cmp100 = icmp slt i64 %indvars.iv.next389, %34
+ br i1 %cmp100, label %for.body103, label %for.cond.cleanup102, !llvm.loop !22
+
+sw.bb111: ; preds = %for.cond.cleanup102
+ %puts318 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
+ %35 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp115362 = icmp sgt i32 %35, 0
+ br i1 %cmp115362, label %for.body118.preheader, label %sw.epilog199
+
+for.body118.preheader: ; preds = %sw.bb111
+ %wide.trip.count424 = zext nneg i32 %35 to i64
+ %xtraiter507 = and i64 %wide.trip.count424, 3
%36 = icmp ult i32 %35, 4
- br i1 %36, label %sw.epilog201.loopexit.unr-lcssa, label %for.body120.preheader.new
-
-for.body120.preheader.new: ; preds = %for.body120.preheader
- %unroll_iter512 = and i64 %wide.trip.count426, 2147483644
- br label %for.body120
-
-for.body120: ; preds = %for.body120, %for.body120.preheader.new
- %indvars.iv420 = phi i64 [ 0, %for.body120.preheader.new ], [ %indvars.iv.next421.3, %for.body120 ]
- %niter513 = phi i64 [ 0, %for.body120.preheader.new ], [ %niter513.next.3, %for.body120 ]
- %indvars425 = trunc i64 %indvars.iv420 to i32
- %mul121 = mul nuw nsw i32 %indvars425, %indvars425
- %mul122322 = or disjoint i32 %mul121, 1
- %mul123321 = mul i32 %mul122322, %indvars425
- %add125323 = or disjoint i32 %mul123321, 3
- %add127 = mul i32 %add125323, %indvars425
- %arrayidx129 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv420
- store i32 %add127, ptr %arrayidx129, align 8, !tbaa !4
- %indvars.iv.next421 = or disjoint i64 %indvars.iv420, 1
- %indvars425.1 = trunc i64 %indvars.iv.next421 to i32
- %mul121.1 = mul nuw nsw i32 %indvars425.1, %indvars425.1
- %mul122322.1 = add nuw nsw i32 %mul121.1, 1
- %mul123321.1 = mul i32 %mul122322.1, %indvars425.1
- %add125323.1 = add i32 %mul123321.1, 3
- %add127.1 = mul i32 %add125323.1, %indvars425.1
- %arrayidx129.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421
- store i32 %add127.1, ptr %arrayidx129.1, align 4, !tbaa !4
- %indvars.iv.next421.1 = or disjoint i64 %indvars.iv420, 2
- %indvars425.2 = trunc i64 %indvars.iv.next421.1 to i32
- %mul121.2 = mul nuw nsw i32 %indvars425.2, %indvars425.2
- %mul122322.2 = or disjoint i32 %mul121.2, 1
- %mul123321.2 = mul i32 %mul122322.2, %indvars425.2
- %add125323.2 = add i32 %mul123321.2, 3
- %add127.2 = mul i32 %add125323.2, %indvars425.2
- %arrayidx129.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421.1
- store i32 %add127.2, ptr %arrayidx129.2, align 8, !tbaa !4
- %indvars.iv.next421.2 = or disjoint i64 %indvars.iv420, 3
- %indvars425.3 = trunc i64 %indvars.iv.next421.2 to i32
- %mul121.3 = mul nuw nsw i32 %indvars425.3, %indvars425.3
- %mul122322.3 = add nuw nsw i32 %mul121.3, 1
- %mul123321.3 = mul i32 %mul122322.3, %indvars425.3
- %add125323.3 = add i32 %mul123321.3, 3
- %add127.3 = mul i32 %add125323.3, %indvars425.3
- %arrayidx129.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next421.2
- store i32 %add127.3, ptr %arrayidx129.3, align 4, !tbaa !4
- %indvars.iv.next421.3 = add nuw nsw i64 %indvars.iv420, 4
- %niter513.next.3 = add i64 %niter513, 4
- %niter513.ncmp.3 = icmp eq i64 %niter513.next.3, %unroll_iter512
- br i1 %niter513.ncmp.3, label %sw.epilog201.loopexit.unr-lcssa, label %for.body120, !llvm.loop !23
-
-sw.bb133: ; preds = %for.cond.cleanup104
- %puts318 = call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
- %37 = load i32, ptr %len, align 4, !tbaa !4
- %cmp137362 = icmp sgt i32 %37, 0
- br i1 %cmp137362, label %for.body140.preheader, label %sw.epilog201
-
-for.body140.preheader: ; preds = %sw.bb133
- %wide.trip.count418 = zext nneg i32 %37 to i64
- %xtraiter504 = and i64 %wide.trip.count418, 3
+ br i1 %36, label %sw.epilog199.loopexit.unr-lcssa, label %for.body118.preheader.new
+
+for.body118.preheader.new: ; preds = %for.body118.preheader
+ %unroll_iter510 = and i64 %wide.trip.count424, 2147483644
+ br label %for.body118
+
+for.body118: ; preds = %for.body118, %for.body118.preheader.new
+ %indvars.iv418 = phi i64 [ 0, %for.body118.preheader.new ], [ %indvars.iv.next419.3, %for.body118 ]
+ %niter511 = phi i64 [ 0, %for.body118.preheader.new ], [ %niter511.next.3, %for.body118 ]
+ %indvars423 = trunc i64 %indvars.iv418 to i32
+ %mul119 = mul nuw nsw i32 %indvars423, %indvars423
+ %mul120320 = or disjoint i32 %mul119, 1
+ %mul121319 = mul i32 %mul120320, %indvars423
+ %add123321 = or disjoint i32 %mul121319, 3
+ %add125 = mul i32 %add123321, %indvars423
+ %arrayidx127 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv418
+ store i32 %add125, ptr %arrayidx127, align 8, !tbaa !4
+ %indvars.iv.next419 = or disjoint i64 %indvars.iv418, 1
+ %indvars423.1 = trunc i64 %indvars.iv.next419 to i32
+ %mul119.1 = mul nuw nsw i32 %indvars423.1, %indvars423.1
+ %mul120320.1 = add nuw nsw i32 %mul119.1, 1
+ %mul121319.1 = mul i32 %mul120320.1, %indvars423.1
+ %add123321.1 = add i32 %mul121319.1, 3
+ %add125.1 = mul i32 %add123321.1, %indvars423.1
+ %arrayidx127.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next419
+ store i32 %add125.1, ptr %arrayidx127.1, align 4, !tbaa !4
+ %indvars.iv.next419.1 = or disjoint i64 %indvars.iv418, 2
+ %indvars423.2 = trunc i64 %indvars.iv.next419.1 to i32
+ %mul119.2 = mul nuw nsw i32 %indvars423.2, %indvars423.2
+ %mul120320.2 = or disjoint i32 %mul119.2, 1
+ %mul121319.2 = mul i32 %mul120320.2, %indvars423.2
+ %add123321.2 = add i32 %mul121319.2, 3
+ %add125.2 = mul i32 %add123321.2, %indvars423.2
+ %arrayidx127.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next419.1
+ store i32 %add125.2, ptr %arrayidx127.2, align 8, !tbaa !4
+ %indvars.iv.next419.2 = or disjoint i64 %indvars.iv418, 3
+ %indvars423.3 = trunc i64 %indvars.iv.next419.2 to i32
+ %mul119.3 = mul nuw nsw i32 %indvars423.3, %indvars423.3
+ %mul120320.3 = add nuw nsw i32 %mul119.3, 1
+ %mul121319.3 = mul i32 %mul120320.3, %indvars423.3
+ %add123321.3 = add i32 %mul121319.3, 3
+ %add125.3 = mul i32 %add123321.3, %indvars423.3
+ %arrayidx127.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next419.2
+ store i32 %add125.3, ptr %arrayidx127.3, align 4, !tbaa !4
+ %indvars.iv.next419.3 = add nuw nsw i64 %indvars.iv418, 4
+ %niter511.next.3 = add i64 %niter511, 4
+ %niter511.ncmp.3 = icmp eq i64 %niter511.next.3, %unroll_iter510
+ br i1 %niter511.ncmp.3, label %sw.epilog199.loopexit.unr-lcssa, label %for.body118, !llvm.loop !23
+
+sw.bb131: ; preds = %for.cond.cleanup102
+ %puts316 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
+ %37 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp135360 = icmp sgt i32 %37, 0
+ br i1 %cmp135360, label %for.body138.preheader, label %sw.epilog199
+
+for.body138.preheader: ; preds = %sw.bb131
+ %wide.trip.count416 = zext nneg i32 %37 to i64
+ %xtraiter502 = and i64 %wide.trip.count416, 3
%38 = icmp ult i32 %37, 4
- br i1 %38, label %sw.epilog201.loopexit484.unr-lcssa, label %for.body140.preheader.new
-
-for.body140.preheader.new: ; preds = %for.body140.preheader
- %unroll_iter507 = and i64 %wide.trip.count418, 2147483644
- br label %for.body140
-
-for.body140: ; preds = %for.body140, %for.body140.preheader.new
- %indvars.iv414 = phi i64 [ 0, %for.body140.preheader.new ], [ %indvars.iv.next415.3, %for.body140 ]
- %niter508 = phi i64 [ 0, %for.body140.preheader.new ], [ %niter508.next.3, %for.body140 ]
- %indvars.iv.next415 = or disjoint i64 %indvars.iv414, 1
- %indvars416 = trunc i64 %indvars.iv.next415 to i32
- %39 = trunc nuw nsw i64 %indvars.iv414 to i32
- %add142 = mul i32 %indvars416, %39
- %add143 = or disjoint i32 %add142, 3
- %arrayidx145 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv414
- store i32 %add143, ptr %arrayidx145, align 8, !tbaa !4
- %indvars.iv.next415.1 = or disjoint i64 %indvars.iv414, 2
- %indvars416.1 = trunc i64 %indvars.iv.next415.1 to i32
- %40 = trunc nuw nsw i64 %indvars.iv.next415 to i32
- %add142.1 = mul i32 %indvars416.1, %40
- %add143.1 = add nsw i32 %add142.1, 3
- %arrayidx145.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415
- store i32 %add143.1, ptr %arrayidx145.1, align 4, !tbaa !4
- %indvars.iv.next415.2 = or disjoint i64 %indvars.iv414, 3
- %indvars416.2 = trunc i64 %indvars.iv.next415.2 to i32
- %41 = trunc nuw nsw i64 %indvars.iv.next415.1 to i32
- %add142.2 = mul i32 %indvars416.2, %41
- %add143.2 = add nsw i32 %add142.2, 3
- %arrayidx145.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415.1
- store i32 %add143.2, ptr %arrayidx145.2, align 8, !tbaa !4
- %indvars.iv.next415.3 = add nuw nsw i64 %indvars.iv414, 4
- %indvars416.3 = trunc i64 %indvars.iv.next415.3 to i32
- %42 = trunc nuw nsw i64 %indvars.iv.next415.2 to i32
- %add142.3 = mul i32 %indvars416.3, %42
- %add143.3 = or disjoint i32 %add142.3, 3
- %arrayidx145.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next415.2
- store i32 %add143.3, ptr %arrayidx145.3, align 4, !tbaa !4
- %niter508.next.3 = add i64 %niter508, 4
- %niter508.ncmp.3 = icmp eq i64 %niter508.next.3, %unroll_iter507
- br i1 %niter508.ncmp.3, label %sw.epilog201.loopexit484.unr-lcssa, label %for.body140, !llvm.loop !24
-
-sw.bb149: ; preds = %for.cond.cleanup104
- %puts315 = call i32 @puts(ptr nonnull dereferenceable(1) @str.30)
- %43 = load i32, ptr %len, align 4, !tbaa !4
- %cmp153360 = icmp sgt i32 %43, 0
- br i1 %cmp153360, label %for.body156.preheader, label %sw.epilog201
-
-for.body156.preheader: ; preds = %sw.bb149
- %wide.trip.count412 = zext nneg i32 %43 to i64
- %xtraiter499 = and i64 %wide.trip.count412, 3
+ br i1 %38, label %sw.epilog199.loopexit482.unr-lcssa, label %for.body138.preheader.new
+
+for.body138.preheader.new: ; preds = %for.body138.preheader
+ %unroll_iter505 = and i64 %wide.trip.count416, 2147483644
+ br label %for.body138
+
+for.body138: ; preds = %for.body138, %for.body138.preheader.new
+ %indvars.iv412 = phi i64 [ 0, %for.body138.preheader.new ], [ %indvars.iv.next413.3, %for.body138 ]
+ %niter506 = phi i64 [ 0, %for.body138.preheader.new ], [ %niter506.next.3, %for.body138 ]
+ %indvars.iv.next413 = or disjoint i64 %indvars.iv412, 1
+ %indvars414 = trunc i64 %indvars.iv.next413 to i32
+ %39 = trunc nuw nsw i64 %indvars.iv412 to i32
+ %add140 = mul i32 %indvars414, %39
+ %add141 = or disjoint i32 %add140, 3
+ %arrayidx143 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv412
+ store i32 %add141, ptr %arrayidx143, align 8, !tbaa !4
+ %indvars.iv.next413.1 = or disjoint i64 %indvars.iv412, 2
+ %indvars414.1 = trunc i64 %indvars.iv.next413.1 to i32
+ %40 = trunc nuw nsw i64 %indvars.iv.next413 to i32
+ %add140.1 = mul i32 %indvars414.1, %40
+ %add141.1 = add nsw i32 %add140.1, 3
+ %arrayidx143.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next413
+ store i32 %add141.1, ptr %arrayidx143.1, align 4, !tbaa !4
+ %indvars.iv.next413.2 = or disjoint i64 %indvars.iv412, 3
+ %indvars414.2 = trunc i64 %indvars.iv.next413.2 to i32
+ %41 = trunc nuw nsw i64 %indvars.iv.next413.1 to i32
+ %add140.2 = mul i32 %indvars414.2, %41
+ %add141.2 = add nsw i32 %add140.2, 3
+ %arrayidx143.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next413.1
+ store i32 %add141.2, ptr %arrayidx143.2, align 8, !tbaa !4
+ %indvars.iv.next413.3 = add nuw nsw i64 %indvars.iv412, 4
+ %indvars414.3 = trunc i64 %indvars.iv.next413.3 to i32
+ %42 = trunc nuw nsw i64 %indvars.iv.next413.2 to i32
+ %add140.3 = mul i32 %indvars414.3, %42
+ %add141.3 = or disjoint i32 %add140.3, 3
+ %arrayidx143.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next413.2
+ store i32 %add141.3, ptr %arrayidx143.3, align 4, !tbaa !4
+ %niter506.next.3 = add i64 %niter506, 4
+ %niter506.ncmp.3 = icmp eq i64 %niter506.next.3, %unroll_iter505
+ br i1 %niter506.ncmp.3, label %sw.epilog199.loopexit482.unr-lcssa, label %for.body138, !llvm.loop !24
+
+sw.bb147: ; preds = %for.cond.cleanup102
+ %puts313 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
+ %43 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp151358 = icmp sgt i32 %43, 0
+ br i1 %cmp151358, label %for.body154.preheader, label %sw.epilog199
+
+for.body154.preheader: ; preds = %sw.bb147
+ %wide.trip.count410 = zext nneg i32 %43 to i64
+ %xtraiter497 = and i64 %wide.trip.count410, 3
%44 = icmp ult i32 %43, 4
- br i1 %44, label %sw.epilog201.loopexit485.unr-lcssa, label %for.body156.preheader.new
-
-for.body156.preheader.new: ; preds = %for.body156.preheader
- %unroll_iter502 = and i64 %wide.trip.count412, 2147483644
- br label %for.body156
-
-for.body156: ; preds = %for.body156, %for.body156.preheader.new
- %indvars.iv407 = phi i64 [ 0, %for.body156.preheader.new ], [ %indvars.iv.next408.3, %for.body156 ]
- %niter503 = phi i64 [ 0, %for.body156.preheader.new ], [ %niter503.next.3, %for.body156 ]
- %45 = trunc nuw nsw i64 %indvars.iv407 to i32
- %mul158316 = mul i32 %45, %45
- %46 = trunc i64 %indvars.iv407 to i32
+ br i1 %44, label %sw.epilog199.loopexit483.unr-lcssa, label %for.body154.preheader.new
+
+for.body154.preheader.new: ; preds = %for.body154.preheader
+ %unroll_iter500 = and i64 %wide.trip.count410, 2147483644
+ br label %for.body154
+
+for.body154: ; preds = %for.body154, %for.body154.preheader.new
+ %indvars.iv405 = phi i64 [ 0, %for.body154.preheader.new ], [ %indvars.iv.next406.3, %for.body154 ]
+ %niter501 = phi i64 [ 0, %for.body154.preheader.new ], [ %niter501.next.3, %for.body154 ]
+ %45 = trunc nuw nsw i64 %indvars.iv405 to i32
+ %mul156314 = mul i32 %45, %45
+ %46 = trunc i64 %indvars.iv405 to i32
%47 = add i32 %46, -1
- %sub160 = mul i32 %mul158316, %47
- %arrayidx162 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv407
- store i32 %sub160, ptr %arrayidx162, align 8, !tbaa !4
- %indvars.iv.next408 = or disjoint i64 %indvars.iv407, 1
- %48 = trunc nuw nsw i64 %indvars.iv.next408 to i32
- %mul158316.1 = mul i32 %48, %48
- %49 = trunc i64 %indvars.iv.next408 to i32
+ %sub158 = mul i32 %mul156314, %47
+ %arrayidx160 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv405
+ store i32 %sub158, ptr %arrayidx160, align 8, !tbaa !4
+ %indvars.iv.next406 = or disjoint i64 %indvars.iv405, 1
+ %48 = trunc nuw nsw i64 %indvars.iv.next406 to i32
+ %mul156314.1 = mul i32 %48, %48
+ %49 = trunc i64 %indvars.iv.next406 to i32
%50 = add nsw i32 %49, -1
- %sub160.1 = mul i32 %mul158316.1, %50
- %arrayidx162.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408
- store i32 %sub160.1, ptr %arrayidx162.1, align 4, !tbaa !4
- %indvars.iv.next408.1 = or disjoint i64 %indvars.iv407, 2
- %51 = trunc nuw nsw i64 %indvars.iv.next408.1 to i32
- %mul158316.2 = mul i32 %51, %51
- %52 = trunc i64 %indvars.iv.next408.1 to i32
+ %sub158.1 = mul i32 %mul156314.1, %50
+ %arrayidx160.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next406
+ store i32 %sub158.1, ptr %arrayidx160.1, align 4, !tbaa !4
+ %indvars.iv.next406.1 = or disjoint i64 %indvars.iv405, 2
+ %51 = trunc nuw nsw i64 %indvars.iv.next406.1 to i32
+ %mul156314.2 = mul i32 %51, %51
+ %52 = trunc i64 %indvars.iv.next406.1 to i32
%53 = add nsw i32 %52, -1
- %sub160.2 = mul i32 %mul158316.2, %53
- %arrayidx162.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408.1
- store i32 %sub160.2, ptr %arrayidx162.2, align 8, !tbaa !4
- %indvars.iv.next408.2 = or disjoint i64 %indvars.iv407, 3
- %54 = trunc nuw nsw i64 %indvars.iv.next408.2 to i32
- %mul158316.3 = mul i32 %54, %54
- %55 = trunc i64 %indvars.iv.next408.2 to i32
+ %sub158.2 = mul i32 %mul156314.2, %53
+ %arrayidx160.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next406.1
+ store i32 %sub158.2, ptr %arrayidx160.2, align 8, !tbaa !4
+ %indvars.iv.next406.2 = or disjoint i64 %indvars.iv405, 3
+ %54 = trunc nuw nsw i64 %indvars.iv.next406.2 to i32
+ %mul156314.3 = mul i32 %54, %54
+ %55 = trunc i64 %indvars.iv.next406.2 to i32
%56 = add nsw i32 %55, -1
- %sub160.3 = mul i32 %mul158316.3, %56
- %arrayidx162.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next408.2
- store i32 %sub160.3, ptr %arrayidx162.3, align 4, !tbaa !4
- %indvars.iv.next408.3 = add nuw nsw i64 %indvars.iv407, 4
- %niter503.next.3 = add i64 %niter503, 4
- %niter503.ncmp.3 = icmp eq i64 %niter503.next.3, %unroll_iter502
- br i1 %niter503.ncmp.3, label %sw.epilog201.loopexit485.unr-lcssa, label %for.body156, !llvm.loop !25
-
-sw.bb166: ; preds = %for.cond.cleanup104
- %puts311 = call i32 @puts(ptr nonnull dereferenceable(1) @str.29)
- %57 = load i32, ptr %len, align 4, !tbaa !4
- %cmp170358 = icmp sgt i32 %57, 0
- br i1 %cmp170358, label %for.body173.preheader, label %sw.epilog201
-
-for.body173.preheader: ; preds = %sw.bb166
- %wide.trip.count405 = zext nneg i32 %57 to i64
- %xtraiter494 = and i64 %wide.trip.count405, 3
+ %sub158.3 = mul i32 %mul156314.3, %56
+ %arrayidx160.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next406.2
+ store i32 %sub158.3, ptr %arrayidx160.3, align 4, !tbaa !4
+ %indvars.iv.next406.3 = add nuw nsw i64 %indvars.iv405, 4
+ %niter501.next.3 = add i64 %niter501, 4
+ %niter501.ncmp.3 = icmp eq i64 %niter501.next.3, %unroll_iter500
+ br i1 %niter501.ncmp.3, label %sw.epilog199.loopexit483.unr-lcssa, label %for.body154, !llvm.loop !25
+
+sw.bb164: ; preds = %for.cond.cleanup102
+ %puts309 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.27)
+ %57 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp168356 = icmp sgt i32 %57, 0
+ br i1 %cmp168356, label %for.body171.preheader, label %sw.epilog199
+
+for.body171.preheader: ; preds = %sw.bb164
+ %wide.trip.count403 = zext nneg i32 %57 to i64
+ %xtraiter492 = and i64 %wide.trip.count403, 3
%58 = icmp ult i32 %57, 4
- br i1 %58, label %sw.epilog201.loopexit486.unr-lcssa, label %for.body173.preheader.new
-
-for.body173.preheader.new: ; preds = %for.body173.preheader
- %unroll_iter497 = and i64 %wide.trip.count405, 2147483644
- br label %for.body173
-
-for.body173: ; preds = %for.body173, %for.body173.preheader.new
- %indvars.iv401 = phi i64 [ 0, %for.body173.preheader.new ], [ %indvars.iv.next402.3, %for.body173 ]
- %niter498 = phi i64 [ 0, %for.body173.preheader.new ], [ %niter498.next.3, %for.body173 ]
- %indvars.iv.next402 = or disjoint i64 %indvars.iv401, 1
- %indvars403 = trunc i64 %indvars.iv.next402 to i32
- %59 = trunc nuw nsw i64 %indvars.iv401 to i32
- %mul175312 = mul i32 %indvars403, %59
- %add177314 = or disjoint i32 %mul175312, 3
- %add179 = mul i32 %add177314, %59
- %arrayidx181 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv401
- store i32 %add179, ptr %arrayidx181, align 8, !tbaa !4
- %indvars.iv.next402.1 = or disjoint i64 %indvars.iv401, 2
- %indvars403.1 = trunc i64 %indvars.iv.next402.1 to i32
- %60 = trunc nuw nsw i64 %indvars.iv.next402 to i32
- %mul175312.1 = mul i32 %indvars403.1, %60
- %add177314.1 = add i32 %mul175312.1, 3
- %add179.1 = mul i32 %add177314.1, %60
- %arrayidx181.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402
- store i32 %add179.1, ptr %arrayidx181.1, align 4, !tbaa !4
- %indvars.iv.next402.2 = or disjoint i64 %indvars.iv401, 3
- %indvars403.2 = trunc i64 %indvars.iv.next402.2 to i32
- %61 = trunc nuw nsw i64 %indvars.iv.next402.1 to i32
- %mul175312.2 = mul i32 %indvars403.2, %61
- %add177314.2 = add i32 %mul175312.2, 3
- %add179.2 = mul i32 %add177314.2, %61
- %arrayidx181.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402.1
- store i32 %add179.2, ptr %arrayidx181.2, align 8, !tbaa !4
- %indvars.iv.next402.3 = add nuw nsw i64 %indvars.iv401, 4
- %indvars403.3 = trunc i64 %indvars.iv.next402.3 to i32
- %62 = trunc nuw nsw i64 %indvars.iv.next402.2 to i32
- %mul175312.3 = mul i32 %indvars403.3, %62
- %add177314.3 = or disjoint i32 %mul175312.3, 3
- %add179.3 = mul i32 %add177314.3, %62
- %arrayidx181.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next402.2
- store i32 %add179.3, ptr %arrayidx181.3, align 4, !tbaa !4
- %niter498.next.3 = add i64 %niter498, 4
- %niter498.ncmp.3 = icmp eq i64 %niter498.next.3, %unroll_iter497
- br i1 %niter498.ncmp.3, label %sw.epilog201.loopexit486.unr-lcssa, label %for.body173, !llvm.loop !26
-
-sw.bb185: ; preds = %for.cond.cleanup104
- %puts309 = call i32 @puts(ptr nonnull dereferenceable(1) @str.28)
- %63 = load i32, ptr %len, align 4, !tbaa !4
- %cmp189356 = icmp sgt i32 %63, 0
- br i1 %cmp189356, label %for.body192.preheader, label %sw.epilog201
-
-for.body192.preheader: ; preds = %sw.bb185
- %wide.trip.count399 = zext nneg i32 %63 to i64
- %xtraiter489 = and i64 %wide.trip.count399, 3
+ br i1 %58, label %sw.epilog199.loopexit484.unr-lcssa, label %for.body171.preheader.new
+
+for.body171.preheader.new: ; preds = %for.body171.preheader
+ %unroll_iter495 = and i64 %wide.trip.count403, 2147483644
+ br label %for.body171
+
+for.body171: ; preds = %for.body171, %for.body171.preheader.new
+ %indvars.iv399 = phi i64 [ 0, %for.body171.preheader.new ], [ %indvars.iv.next400.3, %for.body171 ]
+ %niter496 = phi i64 [ 0, %for.body171.preheader.new ], [ %niter496.next.3, %for.body171 ]
+ %indvars.iv.next400 = or disjoint i64 %indvars.iv399, 1
+ %indvars401 = trunc i64 %indvars.iv.next400 to i32
+ %59 = trunc nuw nsw i64 %indvars.iv399 to i32
+ %mul173310 = mul i32 %indvars401, %59
+ %add175312 = or disjoint i32 %mul173310, 3
+ %add177 = mul i32 %add175312, %59
+ %arrayidx179 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv399
+ store i32 %add177, ptr %arrayidx179, align 8, !tbaa !4
+ %indvars.iv.next400.1 = or disjoint i64 %indvars.iv399, 2
+ %indvars401.1 = trunc i64 %indvars.iv.next400.1 to i32
+ %60 = trunc nuw nsw i64 %indvars.iv.next400 to i32
+ %mul173310.1 = mul i32 %indvars401.1, %60
+ %add175312.1 = add i32 %mul173310.1, 3
+ %add177.1 = mul i32 %add175312.1, %60
+ %arrayidx179.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next400
+ store i32 %add177.1, ptr %arrayidx179.1, align 4, !tbaa !4
+ %indvars.iv.next400.2 = or disjoint i64 %indvars.iv399, 3
+ %indvars401.2 = trunc i64 %indvars.iv.next400.2 to i32
+ %61 = trunc nuw nsw i64 %indvars.iv.next400.1 to i32
+ %mul173310.2 = mul i32 %indvars401.2, %61
+ %add175312.2 = add i32 %mul173310.2, 3
+ %add177.2 = mul i32 %add175312.2, %61
+ %arrayidx179.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next400.1
+ store i32 %add177.2, ptr %arrayidx179.2, align 8, !tbaa !4
+ %indvars.iv.next400.3 = add nuw nsw i64 %indvars.iv399, 4
+ %indvars401.3 = trunc i64 %indvars.iv.next400.3 to i32
+ %62 = trunc nuw nsw i64 %indvars.iv.next400.2 to i32
+ %mul173310.3 = mul i32 %indvars401.3, %62
+ %add175312.3 = or disjoint i32 %mul173310.3, 3
+ %add177.3 = mul i32 %add175312.3, %62
+ %arrayidx179.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next400.2
+ store i32 %add177.3, ptr %arrayidx179.3, align 4, !tbaa !4
+ %niter496.next.3 = add i64 %niter496, 4
+ %niter496.ncmp.3 = icmp eq i64 %niter496.next.3, %unroll_iter495
+ br i1 %niter496.ncmp.3, label %sw.epilog199.loopexit484.unr-lcssa, label %for.body171, !llvm.loop !26
+
+sw.bb183: ; preds = %for.cond.cleanup102
+ %puts307 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.26)
+ %63 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp187354 = icmp sgt i32 %63, 0
+ br i1 %cmp187354, label %for.body190.preheader, label %sw.epilog199
+
+for.body190.preheader: ; preds = %sw.bb183
+ %wide.trip.count397 = zext nneg i32 %63 to i64
+ %xtraiter487 = and i64 %wide.trip.count397, 3
%64 = icmp ult i32 %63, 4
- br i1 %64, label %sw.epilog201.loopexit487.unr-lcssa, label %for.body192.preheader.new
-
-for.body192.preheader.new: ; preds = %for.body192.preheader
- %unroll_iter492 = and i64 %wide.trip.count399, 2147483644
- br label %for.body192
-
-for.body192: ; preds = %for.body192, %for.body192.preheader.new
- %indvars.iv394 = phi i64 [ 0, %for.body192.preheader.new ], [ %indvars.iv.next395.3, %for.body192 ]
- %niter493 = phi i64 [ 0, %for.body192.preheader.new ], [ %niter493.next.3, %for.body192 ]
- %indvars398 = trunc i64 %indvars.iv394 to i32
- %mul194310 = or disjoint i32 %indvars398, 3
- %add195 = mul i32 %mul194310, %indvars398
- %arrayidx197 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv394
- store i32 %add195, ptr %arrayidx197, align 8, !tbaa !4
- %indvars.iv.next395 = or disjoint i64 %indvars.iv394, 1
- %indvars398.1 = trunc i64 %indvars.iv.next395 to i32
- %mul194310.1 = add nuw i32 %indvars398.1, 3
- %add195.1 = mul i32 %mul194310.1, %indvars398.1
- %arrayidx197.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395
- store i32 %add195.1, ptr %arrayidx197.1, align 4, !tbaa !4
- %indvars.iv.next395.1 = or disjoint i64 %indvars.iv394, 2
- %indvars398.2 = trunc i64 %indvars.iv.next395.1 to i32
- %mul194310.2 = add nuw i32 %indvars398.2, 3
- %add195.2 = mul i32 %mul194310.2, %indvars398.2
- %arrayidx197.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395.1
- store i32 %add195.2, ptr %arrayidx197.2, align 8, !tbaa !4
- %indvars.iv.next395.2 = or disjoint i64 %indvars.iv394, 3
- %indvars398.3 = trunc i64 %indvars.iv.next395.2 to i32
- %mul194310.3 = add nuw i32 %indvars398.3, 3
- %add195.3 = mul i32 %mul194310.3, %indvars398.3
- %arrayidx197.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next395.2
- store i32 %add195.3, ptr %arrayidx197.3, align 4, !tbaa !4
- %indvars.iv.next395.3 = add nuw nsw i64 %indvars.iv394, 4
- %niter493.next.3 = add i64 %niter493, 4
- %niter493.ncmp.3 = icmp eq i64 %niter493.next.3, %unroll_iter492
- br i1 %niter493.ncmp.3, label %sw.epilog201.loopexit487.unr-lcssa, label %for.body192, !llvm.loop !27
-
-sw.epilog201.loopexit.unr-lcssa: ; preds = %for.body120, %for.body120.preheader
- %indvars.iv420.unr = phi i64 [ 0, %for.body120.preheader ], [ %indvars.iv.next421.3, %for.body120 ]
- %lcmp.mod511.not = icmp eq i64 %xtraiter509, 0
- br i1 %lcmp.mod511.not, label %sw.epilog201, label %for.body120.epil
-
-for.body120.epil: ; preds = %sw.epilog201.loopexit.unr-lcssa, %for.body120.epil
- %indvars.iv420.epil = phi i64 [ %indvars.iv.next421.epil, %for.body120.epil ], [ %indvars.iv420.unr, %sw.epilog201.loopexit.unr-lcssa ]
- %epil.iter510 = phi i64 [ %epil.iter510.next, %for.body120.epil ], [ 0, %sw.epilog201.loopexit.unr-lcssa ]
- %indvars425.epil = trunc i64 %indvars.iv420.epil to i32
- %mul121.epil = mul nuw nsw i32 %indvars425.epil, %indvars425.epil
- %mul122322.epil = add nuw i32 %mul121.epil, 1
- %mul123321.epil = mul i32 %mul122322.epil, %indvars425.epil
- %add125323.epil = add i32 %mul123321.epil, 3
- %add127.epil = mul i32 %add125323.epil, %indvars425.epil
- %arrayidx129.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv420.epil
- store i32 %add127.epil, ptr %arrayidx129.epil, align 4, !tbaa !4
- %indvars.iv.next421.epil = add nuw nsw i64 %indvars.iv420.epil, 1
- %epil.iter510.next = add i64 %epil.iter510, 1
- %epil.iter510.cmp.not = icmp eq i64 %epil.iter510.next, %xtraiter509
- br i1 %epil.iter510.cmp.not, label %sw.epilog201, label %for.body120.epil, !llvm.loop !28
-
-sw.epilog201.loopexit484.unr-lcssa: ; preds = %for.body140, %for.body140.preheader
- %indvars.iv414.unr = phi i64 [ 0, %for.body140.preheader ], [ %indvars.iv.next415.3, %for.body140 ]
- %lcmp.mod506.not = icmp eq i64 %xtraiter504, 0
- br i1 %lcmp.mod506.not, label %sw.epilog201, label %for.body140.epil
-
-for.body140.epil: ; preds = %sw.epilog201.loopexit484.unr-lcssa, %for.body140.epil
- %indvars.iv414.epil = phi i64 [ %indvars.iv.next415.epil, %for.body140.epil ], [ %indvars.iv414.unr, %sw.epilog201.loopexit484.unr-lcssa ]
- %epil.iter505 = phi i64 [ %epil.iter505.next, %for.body140.epil ], [ 0, %sw.epilog201.loopexit484.unr-lcssa ]
- %indvars.iv.next415.epil = add nuw nsw i64 %indvars.iv414.epil, 1
- %indvars416.epil = trunc i64 %indvars.iv.next415.epil to i32
- %65 = trunc nuw nsw i64 %indvars.iv414.epil to i32
- %add142.epil = mul i32 %indvars416.epil, %65
- %add143.epil = add nsw i32 %add142.epil, 3
- %arrayidx145.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv414.epil
- store i32 %add143.epil, ptr %arrayidx145.epil, align 4, !tbaa !4
- %epil.iter505.next = add i64 %epil.iter505, 1
- %epil.iter505.cmp.not = icmp eq i64 %epil.iter505.next, %xtraiter504
- br i1 %epil.iter505.cmp.not, label %sw.epilog201, label %for.body140.epil, !llvm.loop !29
-
-sw.epilog201.loopexit485.unr-lcssa: ; preds = %for.body156, %for.body156.preheader
- %indvars.iv407.unr = phi i64 [ 0, %for.body156.preheader ], [ %indvars.iv.next408.3, %for.body156 ]
- %lcmp.mod501.not = icmp eq i64 %xtraiter499, 0
- br i1 %lcmp.mod501.not, label %sw.epilog201, label %for.body156.epil
-
-for.body156.epil: ; preds = %sw.epilog201.loopexit485.unr-lcssa, %for.body156.epil
- %indvars.iv407.epil = phi i64 [ %indvars.iv.next408.epil, %for.body156.epil ], [ %indvars.iv407.unr, %sw.epilog201.loopexit485.unr-lcssa ]
- %epil.iter500 = phi i64 [ %epil.iter500.next, %for.body156.epil ], [ 0, %sw.epilog201.loopexit485.unr-lcssa ]
- %66 = trunc nuw nsw i64 %indvars.iv407.epil to i32
- %mul158316.epil = mul i32 %66, %66
- %67 = trunc i64 %indvars.iv407.epil to i32
+ br i1 %64, label %sw.epilog199.loopexit485.unr-lcssa, label %for.body190.preheader.new
+
+for.body190.preheader.new: ; preds = %for.body190.preheader
+ %unroll_iter490 = and i64 %wide.trip.count397, 2147483644
+ br label %for.body190
+
+for.body190: ; preds = %for.body190, %for.body190.preheader.new
+ %indvars.iv392 = phi i64 [ 0, %for.body190.preheader.new ], [ %indvars.iv.next393.3, %for.body190 ]
+ %niter491 = phi i64 [ 0, %for.body190.preheader.new ], [ %niter491.next.3, %for.body190 ]
+ %indvars396 = trunc i64 %indvars.iv392 to i32
+ %mul192308 = or disjoint i32 %indvars396, 3
+ %add193 = mul i32 %mul192308, %indvars396
+ %arrayidx195 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv392
+ store i32 %add193, ptr %arrayidx195, align 8, !tbaa !4
+ %indvars.iv.next393 = or disjoint i64 %indvars.iv392, 1
+ %indvars396.1 = trunc i64 %indvars.iv.next393 to i32
+ %mul192308.1 = add nuw i32 %indvars396.1, 3
+ %add193.1 = mul i32 %mul192308.1, %indvars396.1
+ %arrayidx195.1 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next393
+ store i32 %add193.1, ptr %arrayidx195.1, align 4, !tbaa !4
+ %indvars.iv.next393.1 = or disjoint i64 %indvars.iv392, 2
+ %indvars396.2 = trunc i64 %indvars.iv.next393.1 to i32
+ %mul192308.2 = add nuw i32 %indvars396.2, 3
+ %add193.2 = mul i32 %mul192308.2, %indvars396.2
+ %arrayidx195.2 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next393.1
+ store i32 %add193.2, ptr %arrayidx195.2, align 8, !tbaa !4
+ %indvars.iv.next393.2 = or disjoint i64 %indvars.iv392, 3
+ %indvars396.3 = trunc i64 %indvars.iv.next393.2 to i32
+ %mul192308.3 = add nuw i32 %indvars396.3, 3
+ %add193.3 = mul i32 %mul192308.3, %indvars396.3
+ %arrayidx195.3 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv.next393.2
+ store i32 %add193.3, ptr %arrayidx195.3, align 4, !tbaa !4
+ %indvars.iv.next393.3 = add nuw nsw i64 %indvars.iv392, 4
+ %niter491.next.3 = add i64 %niter491, 4
+ %niter491.ncmp.3 = icmp eq i64 %niter491.next.3, %unroll_iter490
+ br i1 %niter491.ncmp.3, label %sw.epilog199.loopexit485.unr-lcssa, label %for.body190, !llvm.loop !27
+
+sw.epilog199.loopexit.unr-lcssa: ; preds = %for.body118, %for.body118.preheader
+ %indvars.iv418.unr = phi i64 [ 0, %for.body118.preheader ], [ %indvars.iv.next419.3, %for.body118 ]
+ %lcmp.mod509.not = icmp eq i64 %xtraiter507, 0
+ br i1 %lcmp.mod509.not, label %sw.epilog199, label %for.body118.epil
+
+for.body118.epil: ; preds = %sw.epilog199.loopexit.unr-lcssa, %for.body118.epil
+ %indvars.iv418.epil = phi i64 [ %indvars.iv.next419.epil, %for.body118.epil ], [ %indvars.iv418.unr, %sw.epilog199.loopexit.unr-lcssa ]
+ %epil.iter508 = phi i64 [ %epil.iter508.next, %for.body118.epil ], [ 0, %sw.epilog199.loopexit.unr-lcssa ]
+ %indvars423.epil = trunc i64 %indvars.iv418.epil to i32
+ %mul119.epil = mul nuw nsw i32 %indvars423.epil, %indvars423.epil
+ %mul120320.epil = add nuw i32 %mul119.epil, 1
+ %mul121319.epil = mul i32 %mul120320.epil, %indvars423.epil
+ %add123321.epil = add i32 %mul121319.epil, 3
+ %add125.epil = mul i32 %add123321.epil, %indvars423.epil
+ %arrayidx127.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv418.epil
+ store i32 %add125.epil, ptr %arrayidx127.epil, align 4, !tbaa !4
+ %indvars.iv.next419.epil = add nuw nsw i64 %indvars.iv418.epil, 1
+ %epil.iter508.next = add i64 %epil.iter508, 1
+ %epil.iter508.cmp.not = icmp eq i64 %epil.iter508.next, %xtraiter507
+ br i1 %epil.iter508.cmp.not, label %sw.epilog199, label %for.body118.epil, !llvm.loop !28
+
+sw.epilog199.loopexit482.unr-lcssa: ; preds = %for.body138, %for.body138.preheader
+ %indvars.iv412.unr = phi i64 [ 0, %for.body138.preheader ], [ %indvars.iv.next413.3, %for.body138 ]
+ %lcmp.mod504.not = icmp eq i64 %xtraiter502, 0
+ br i1 %lcmp.mod504.not, label %sw.epilog199, label %for.body138.epil
+
+for.body138.epil: ; preds = %sw.epilog199.loopexit482.unr-lcssa, %for.body138.epil
+ %indvars.iv412.epil = phi i64 [ %indvars.iv.next413.epil, %for.body138.epil ], [ %indvars.iv412.unr, %sw.epilog199.loopexit482.unr-lcssa ]
+ %epil.iter503 = phi i64 [ %epil.iter503.next, %for.body138.epil ], [ 0, %sw.epilog199.loopexit482.unr-lcssa ]
+ %indvars.iv.next413.epil = add nuw nsw i64 %indvars.iv412.epil, 1
+ %indvars414.epil = trunc i64 %indvars.iv.next413.epil to i32
+ %65 = trunc nuw nsw i64 %indvars.iv412.epil to i32
+ %add140.epil = mul i32 %indvars414.epil, %65
+ %add141.epil = add nsw i32 %add140.epil, 3
+ %arrayidx143.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv412.epil
+ store i32 %add141.epil, ptr %arrayidx143.epil, align 4, !tbaa !4
+ %epil.iter503.next = add i64 %epil.iter503, 1
+ %epil.iter503.cmp.not = icmp eq i64 %epil.iter503.next, %xtraiter502
+ br i1 %epil.iter503.cmp.not, label %sw.epilog199, label %for.body138.epil, !llvm.loop !29
+
+sw.epilog199.loopexit483.unr-lcssa: ; preds = %for.body154, %for.body154.preheader
+ %indvars.iv405.unr = phi i64 [ 0, %for.body154.preheader ], [ %indvars.iv.next406.3, %for.body154 ]
+ %lcmp.mod499.not = icmp eq i64 %xtraiter497, 0
+ br i1 %lcmp.mod499.not, label %sw.epilog199, label %for.body154.epil
+
+for.body154.epil: ; preds = %sw.epilog199.loopexit483.unr-lcssa, %for.body154.epil
+ %indvars.iv405.epil = phi i64 [ %indvars.iv.next406.epil, %for.body154.epil ], [ %indvars.iv405.unr, %sw.epilog199.loopexit483.unr-lcssa ]
+ %epil.iter498 = phi i64 [ %epil.iter498.next, %for.body154.epil ], [ 0, %sw.epilog199.loopexit483.unr-lcssa ]
+ %66 = trunc nuw nsw i64 %indvars.iv405.epil to i32
+ %mul156314.epil = mul i32 %66, %66
+ %67 = trunc i64 %indvars.iv405.epil to i32
%68 = add i32 %67, -1
- %sub160.epil = mul i32 %mul158316.epil, %68
- %arrayidx162.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv407.epil
- store i32 %sub160.epil, ptr %arrayidx162.epil, align 4, !tbaa !4
- %indvars.iv.next408.epil = add nuw nsw i64 %indvars.iv407.epil, 1
- %epil.iter500.next = add i64 %epil.iter500, 1
- %epil.iter500.cmp.not = icmp eq i64 %epil.iter500.next, %xtraiter499
- br i1 %epil.iter500.cmp.not, label %sw.epilog201, label %for.body156.epil, !llvm.loop !30
-
-sw.epilog201.loopexit486.unr-lcssa: ; preds = %for.body173, %for.body173.preheader
- %indvars.iv401.unr = phi i64 [ 0, %for.body173.preheader ], [ %indvars.iv.next402.3, %for.body173 ]
- %lcmp.mod496.not = icmp eq i64 %xtraiter494, 0
- br i1 %lcmp.mod496.not, label %sw.epilog201, label %for.body173.epil
-
-for.body173.epil: ; preds = %sw.epilog201.loopexit486.unr-lcssa, %for.body173.epil
- %indvars.iv401.epil = phi i64 [ %indvars.iv.next402.epil, %for.body173.epil ], [ %indvars.iv401.unr, %sw.epilog201.loopexit486.unr-lcssa ]
- %epil.iter495 = phi i64 [ %epil.iter495.next, %for.body173.epil ], [ 0, %sw.epilog201.loopexit486.unr-lcssa ]
- %indvars.iv.next402.epil = add nuw nsw i64 %indvars.iv401.epil, 1
- %indvars403.epil = trunc i64 %indvars.iv.next402.epil to i32
- %69 = trunc nuw nsw i64 %indvars.iv401.epil to i32
- %mul175312.epil = mul i32 %indvars403.epil, %69
- %add177314.epil = add i32 %mul175312.epil, 3
- %add179.epil = mul i32 %add177314.epil, %69
- %arrayidx181.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv401.epil
- store i32 %add179.epil, ptr %arrayidx181.epil, align 4, !tbaa !4
- %epil.iter495.next = add i64 %epil.iter495, 1
- %epil.iter495.cmp.not = icmp eq i64 %epil.iter495.next, %xtraiter494
- br i1 %epil.iter495.cmp.not, label %sw.epilog201, label %for.body173.epil, !llvm.loop !31
-
-sw.epilog201.loopexit487.unr-lcssa: ; preds = %for.body192, %for.body192.preheader
- %indvars.iv394.unr = phi i64 [ 0, %for.body192.preheader ], [ %indvars.iv.next395.3, %for.body192 ]
- %lcmp.mod491.not = icmp eq i64 %xtraiter489, 0
- br i1 %lcmp.mod491.not, label %sw.epilog201, label %for.body192.epil
-
-for.body192.epil: ; preds = %sw.epilog201.loopexit487.unr-lcssa, %for.body192.epil
- %indvars.iv394.epil = phi i64 [ %indvars.iv.next395.epil, %for.body192.epil ], [ %indvars.iv394.unr, %sw.epilog201.loopexit487.unr-lcssa ]
- %epil.iter490 = phi i64 [ %epil.iter490.next, %for.body192.epil ], [ 0, %sw.epilog201.loopexit487.unr-lcssa ]
- %indvars398.epil = trunc i64 %indvars.iv394.epil to i32
- %mul194310.epil = add nuw i32 %indvars398.epil, 3
- %add195.epil = mul i32 %mul194310.epil, %indvars398.epil
- %arrayidx197.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv394.epil
- store i32 %add195.epil, ptr %arrayidx197.epil, align 4, !tbaa !4
- %indvars.iv.next395.epil = add nuw nsw i64 %indvars.iv394.epil, 1
- %epil.iter490.next = add i64 %epil.iter490, 1
- %epil.iter490.cmp.not = icmp eq i64 %epil.iter490.next, %xtraiter489
- br i1 %epil.iter490.cmp.not, label %sw.epilog201, label %for.body192.epil, !llvm.loop !32
-
-sw.epilog201: ; preds = %sw.epilog201.loopexit487.unr-lcssa, %for.body192.epil, %sw.epilog201.loopexit486.unr-lcssa, %for.body173.epil, %sw.epilog201.loopexit485.unr-lcssa, %for.body156.epil, %sw.epilog201.loopexit484.unr-lcssa, %for.body140.epil, %sw.epilog201.loopexit.unr-lcssa, %for.body120.epil, %sw.bb185, %sw.bb166, %sw.bb149, %sw.bb133, %sw.bb113, %for.cond.cleanup104
- call void @func3()
+ %sub158.epil = mul i32 %mul156314.epil, %68
+ %arrayidx160.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv405.epil
+ store i32 %sub158.epil, ptr %arrayidx160.epil, align 4, !tbaa !4
+ %indvars.iv.next406.epil = add nuw nsw i64 %indvars.iv405.epil, 1
+ %epil.iter498.next = add i64 %epil.iter498, 1
+ %epil.iter498.cmp.not = icmp eq i64 %epil.iter498.next, %xtraiter497
+ br i1 %epil.iter498.cmp.not, label %sw.epilog199, label %for.body154.epil, !llvm.loop !30
+
+sw.epilog199.loopexit484.unr-lcssa: ; preds = %for.body171, %for.body171.preheader
+ %indvars.iv399.unr = phi i64 [ 0, %for.body171.preheader ], [ %indvars.iv.next400.3, %for.body171 ]
+ %lcmp.mod494.not = icmp eq i64 %xtraiter492, 0
+ br i1 %lcmp.mod494.not, label %sw.epilog199, label %for.body171.epil
+
+for.body171.epil: ; preds = %sw.epilog199.loopexit484.unr-lcssa, %for.body171.epil
+ %indvars.iv399.epil = phi i64 [ %indvars.iv.next400.epil, %for.body171.epil ], [ %indvars.iv399.unr, %sw.epilog199.loopexit484.unr-lcssa ]
+ %epil.iter493 = phi i64 [ %epil.iter493.next, %for.body171.epil ], [ 0, %sw.epilog199.loopexit484.unr-lcssa ]
+ %indvars.iv.next400.epil = add nuw nsw i64 %indvars.iv399.epil, 1
+ %indvars401.epil = trunc i64 %indvars.iv.next400.epil to i32
+ %69 = trunc nuw nsw i64 %indvars.iv399.epil to i32
+ %mul173310.epil = mul i32 %indvars401.epil, %69
+ %add175312.epil = add i32 %mul173310.epil, 3
+ %add177.epil = mul i32 %add175312.epil, %69
+ %arrayidx179.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv399.epil
+ store i32 %add177.epil, ptr %arrayidx179.epil, align 4, !tbaa !4
+ %epil.iter493.next = add i64 %epil.iter493, 1
+ %epil.iter493.cmp.not = icmp eq i64 %epil.iter493.next, %xtraiter492
+ br i1 %epil.iter493.cmp.not, label %sw.epilog199, label %for.body171.epil, !llvm.loop !31
+
+sw.epilog199.loopexit485.unr-lcssa: ; preds = %for.body190, %for.body190.preheader
+ %indvars.iv392.unr = phi i64 [ 0, %for.body190.preheader ], [ %indvars.iv.next393.3, %for.body190 ]
+ %lcmp.mod489.not = icmp eq i64 %xtraiter487, 0
+ br i1 %lcmp.mod489.not, label %sw.epilog199, label %for.body190.epil
+
+for.body190.epil: ; preds = %sw.epilog199.loopexit485.unr-lcssa, %for.body190.epil
+ %indvars.iv392.epil = phi i64 [ %indvars.iv.next393.epil, %for.body190.epil ], [ %indvars.iv392.unr, %sw.epilog199.loopexit485.unr-lcssa ]
+ %epil.iter488 = phi i64 [ %epil.iter488.next, %for.body190.epil ], [ 0, %sw.epilog199.loopexit485.unr-lcssa ]
+ %indvars396.epil = trunc i64 %indvars.iv392.epil to i32
+ %mul192308.epil = add nuw i32 %indvars396.epil, 3
+ %add193.epil = mul i32 %mul192308.epil, %indvars396.epil
+ %arrayidx195.epil = getelementptr inbounds i32, ptr %1, i64 %indvars.iv392.epil
+ store i32 %add193.epil, ptr %arrayidx195.epil, align 4, !tbaa !4
+ %indvars.iv.next393.epil = add nuw nsw i64 %indvars.iv392.epil, 1
+ %epil.iter488.next = add i64 %epil.iter488, 1
+ %epil.iter488.cmp.not = icmp eq i64 %epil.iter488.next, %xtraiter487
+ br i1 %epil.iter488.cmp.not, label %sw.epilog199, label %for.body190.epil, !llvm.loop !32
+
+sw.epilog199: ; preds = %sw.epilog199.loopexit485.unr-lcssa, %for.body190.epil, %sw.epilog199.loopexit484.unr-lcssa, %for.body171.epil, %sw.epilog199.loopexit483.unr-lcssa, %for.body154.epil, %sw.epilog199.loopexit482.unr-lcssa, %for.body138.epil, %sw.epilog199.loopexit.unr-lcssa, %for.body118.epil, %sw.bb183, %sw.bb164, %sw.bb147, %sw.bb131, %sw.bb111, %for.cond.cleanup102
+ tail call void @func3()
unreachable
-if.else202: ; preds = %for.cond.cleanup
- %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
- %70 = load i32, ptr %len, align 4, !tbaa !4
- %cmp206352 = icmp sgt i32 %70, 0
- br i1 %cmp206352, label %for.body209, label %for.cond.cleanup208
+if.else200: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %70 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp204350 = icmp sgt i32 %70, 0
+ br i1 %cmp204350, label %for.body207, label %for.cond.cleanup206
-for.cond.cleanup208: ; preds = %for.body209, %if.else202
- call void @func2()
+for.cond.cleanup206: ; preds = %for.body207, %if.else200
+ tail call void @func2()
unreachable
-for.body209: ; preds = %if.else202, %for.body209
- %indvars.iv386 = phi i64 [ %indvars.iv.next387, %for.body209 ], [ 0, %if.else202 ]
- %arrayidx211 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv386
- %71 = load i32, ptr %arrayidx211, align 4, !tbaa !4
- %call212 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.13, i32 noundef signext %71)
- %indvars.iv.next387 = add nuw nsw i64 %indvars.iv386, 1
- %72 = load i32, ptr %len, align 4, !tbaa !4
+for.body207: ; preds = %if.else200, %for.body207
+ %indvars.iv384 = phi i64 [ %indvars.iv.next385, %for.body207 ], [ 0, %if.else200 ]
+ %arrayidx209 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv384
+ %71 = load i32, ptr %arrayidx209, align 4, !tbaa !4
+ %call210 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %71)
+ %indvars.iv.next385 = add nuw nsw i64 %indvars.iv384, 1
+ %72 = load i32, ptr @len, align 4, !tbaa !4
%73 = sext i32 %72 to i64
- %cmp206 = icmp slt i64 %indvars.iv.next387, %73
- br i1 %cmp206, label %for.body209, label %for.cond.cleanup208, !llvm.loop !33
+ %cmp204 = icmp slt i64 %indvars.iv.next385, %73
+ br i1 %cmp204, label %for.body207, label %for.cond.cleanup206, !llvm.loop !33
}
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
-declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
-
-; Function Attrs: nofree nounwind
-declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
-
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
; Function Attrs: nounwind
-define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
entry:
-; CHECK: larl %r1, buf1
-; CHECK: lg %r2, 8(%r1)
-; CHECK: lg %r11, 0(%r1)
-; CHECK: lg %r13, 32(%r1)
-; CHECK: lg %r3, 16(%r1)
-; CHECK: stg %r3, 0(%r15)
-; CHECK: lg %r15, 24(%r1)
-; CHECK: br %r2
-
%0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
%cmp = icmp eq i32 %0, 0
br i1 %cmp, label %if.then, label %if.else
if.then: ; preds = %entry
- %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.34)
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.32)
%call1 = tail call signext i32 @func1()
unreachable
if.else: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.33)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.31)
ret i32 0
}
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #2 = { noreturn nounwind }
attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-attributes #5 = { nounwind }
-attributes #6 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #7 = { nofree nounwind }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -1004,7 +1005,7 @@ attributes #7 = { nofree nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
!4 = !{!5, !5, i64 0}
!5 = !{!"int", !6, i64 0}
!6 = !{!"omnipotent char", !7, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-00.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-00.ll
index 47c62f3f40396b..b523b7c2c39d06 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-00.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-00.ll
@@ -1,5 +1,6 @@
-; Test output for inline Literal Pool.
-; RUN: clang -o %t %s
+; Test output(simulating inline Literal Pool).
+
+; RUN: clang -O2 -o %t %s
; RUN: %t | FileCheck %s
; CHECK: value_ptr is 954219
; CHECK: value_ptr is 954219
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-01.ll
index 8120fa2a6f6fc5..5a1a02de7c2231 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-01.ll
@@ -1,8 +1,11 @@
-; Test Literal Pool Register R13.
; Test the output.
-; FIXME:
-; Correct Output is:
+; The behavior of local variables between setjmp and longjmp in C is undefined.
+; This means that the C standard does not guarantee what will happen
+; to their values.
+
+; Output from gcc at all optimization levels or clang -O0 is:
+
;First __builtin_setjmp in func1
;Second __builtin_setjmp in func1
;Returned from func4
@@ -10,12 +13,10 @@
;Returned from func3
;value_ptr: 420420
-; TODO: -mbackchain
-; ModuleID = 'builtin-setjmp-longjmp-literal-pool-01.c'
-
-; RUN: clang -o %t %s
+; RUN: clang -O2 -o %t %s
; RUN: %t | FileCheck %s
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-01.c'
source_filename = "builtin-setjmp-longjmp-literal-pool-01.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
target triple = "s390x-unknown-linux-gnu"
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-02.ll
index 2373d5e883874d..1af4d77bd5855a 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-02.ll
@@ -1,8 +1,10 @@
-; Test Literal Pool Register R13.
; Test the output.
-; FIXME:
-; Correct Output is:
+; The behavior of local variables between setjmp and longjmp in C is undefined.
+; This means that the C standard does not guarantee what will happen
+; to their values.
+
+; Output from gcc at all optimization levels or clang -O0 is:
;First __builtin_setjmp in func1
;Second __builtin_setjmp in func1
@@ -31,13 +33,9 @@
;arr: 123454
;arr: 451233
-; TODO: -mbackchain
-; ModuleID = 'builtin-setjmp-longjmp-literal-pool-01.c'
-
-; RUN: clang -o %t %s
+; RUN: clang -O2 -o %t %s
; RUN: %t | FileCheck %s
-
; ModuleID = 'builtin-setjmp-longjmp-literal-pool-02.c'
source_filename = "builtin-setjmp-longjmp-literal-pool-02.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-03.ll
index 3adc7cd4bd284b..90b768f5d2b325 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-03.ll
@@ -1,11 +1,9 @@
-; Test Literal Pool Register R13.
-; Test the output.
-; Gives Correct Result.
-; FIXME: How to pass stdin input to llvm-lit
-; TODO: -mbackchain option.
+; Test output for inline Literal Pool with switch statement.
+; len of malloc is passed as an argument.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t 10 | FileCheck %s
-; RUN: clang -o %t %s
-; RUN: %t < 10| FileCheck %s
; ModuleID = 'builtin-setjmp-longjmp-literal-pool-03.c'
source_filename = "builtin-setjmp-longjmp-literal-pool-03.c"
@@ -58,20 +56,19 @@ module asm ".long 190346"
@buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
@buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
- at .str.3 = private unnamed_addr constant [22 x i8] c"Please enter length: \00", align 2
- at .str.4 = private unnamed_addr constant [3 x i8] c"%d\00", align 2
- at .str.8 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
- at .str.9 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
- at .str.11 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
@str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
- at str.14 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
- at str.15 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
- at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
- at str.17 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
- at str.18 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
- at str.19 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
- at str.20 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
- at str.21 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.13 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.14 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.15 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.16 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.18 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.19 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.20 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.21 = private unnamed_addr constant [30 x i8] c"Usage: program_name <length> \00", align 1
; Function Attrs: noinline noreturn nounwind
define dso_local void @func4() local_unnamed_addr #0 {
@@ -90,7 +87,7 @@ declare void @llvm.eh.sjlj.longjmp(ptr) #2
; Function Attrs: noinline noreturn nounwind
define dso_local void @func3() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
unreachable
}
@@ -98,17 +95,17 @@ entry:
; Function Attrs: noinline noreturn nounwind
define dso_local void @func2() local_unnamed_addr #0 {
entry:
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
unreachable
}
; Function Attrs: noreturn nounwind
-define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+define dso_local noundef signext i32 @func1(i32 noundef signext %len) local_unnamed_addr #3 {
entry:
; CHECK: First __builtin_setjmp in func1
; CHECK: Second __builtin_setjmp in func1
-In func4
+; CHECK: In func4
; CHECK: Returned from func4
; CHECK: value_ptr : 954219
; CHECK: arr: 954219
@@ -121,277 +118,158 @@ In func4
; CHECK: arr: 190346
; CHECK: arr: 420420
; CHECK: arr: 732972
-In func3
+; CHECK: In func3
; CHECK: Returned from func3
-; CHECK: value_ptr: 420420
-; CHECK: arr: 971166
-; CHECK: arr: 123454
-; CHECK: arr: 451233
+; CHECK: value_ptr: 954219
; CHECK: arr: 954219
; CHECK: arr: 466232
; CHECK: arr: 955551
; CHECK: arr: 687823
; CHECK: arr: 555123
-; CHECK: arr: 123454
-; CHECK: arr: 451233
-
- %len = alloca i32, align 4
- call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %len) #5
- store i32 0, ptr %len, align 4, !tbaa !4
- %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3)
- %call1 = call signext i32 (ptr, ...) @__isoc99_scanf(ptr noundef nonnull @.str.4, ptr noundef nonnull %len)
- %0 = alloca [40 x i8], align 8
- %1 = call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #5, !srcloc !8
- %add.ptr = getelementptr inbounds i8, ptr %1, i64 8
- %2 = load i32, ptr %len, align 4, !tbaa !4
- %cmp70 = icmp sgt i32 %2, 0
- br i1 %cmp70, label %for.body.preheader, label %for.cond.cleanup
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+
+ %conv = sext i32 %len to i64
+ %mul = shl nsw i64 %conv, 2
+ %0 = alloca i8, i64 %mul, align 8
+ %1 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #4, !srcloc !4
+ %add.ptr = getelementptr i8, ptr %1, i64 8
+ %cmp76 = icmp sgt i32 %len, 0
+ br i1 %cmp76, label %for.body.preheader, label %for.cond.cleanup
for.body.preheader: ; preds = %entry
- %wide.trip.count = zext nneg i32 %2 to i64
- %xtraiter = and i64 %wide.trip.count, 3
- %3 = icmp ult i32 %2, 4
- br i1 %3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new
-
-for.body.preheader.new: ; preds = %for.body.preheader
- %unroll_iter = and i64 %wide.trip.count, 2147483644
- br label %for.body
-
-for.cond.cleanup.loopexit.unr-lcssa: ; preds = %for.body, %for.body.preheader
- %indvars.iv.unr = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next.3, %for.body ]
- %lcmp.mod.not = icmp eq i64 %xtraiter, 0
- br i1 %lcmp.mod.not, label %for.cond.cleanup, label %for.body.epil
-
-for.body.epil: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil
- %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %for.body.epil ], [ %indvars.iv.unr, %for.cond.cleanup.loopexit.unr-lcssa ]
- %epil.iter = phi i64 [ %epil.iter.next, %for.body.epil ], [ 0, %for.cond.cleanup.loopexit.unr-lcssa ]
- %4 = trunc nuw nsw i64 %indvars.iv.epil to i32
- %rem.epil = urem i32 %4, 10
- %idx.ext.epil = zext nneg i32 %rem.epil to i64
- %add.ptr2.epil = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext.epil
- %5 = load i32, ptr %add.ptr2.epil, align 4, !tbaa !4
- %arrayidx.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.epil
- store i32 %5, ptr %arrayidx.epil, align 4, !tbaa !4
- %indvars.iv.next.epil = add nuw nsw i64 %indvars.iv.epil, 1
- %epil.iter.next = add i64 %epil.iter, 1
- %epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
- br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil, !llvm.loop !9
-
-for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil, %entry
- %6 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
- %cmp3 = icmp eq i32 %6, 0
- br i1 %cmp3, label %if.then, label %if.else35
-
-for.body: ; preds = %for.body, %for.body.preheader.new
- %indvars.iv = phi i64 [ 0, %for.body.preheader.new ], [ %indvars.iv.next.3, %for.body ]
- %niter = phi i64 [ 0, %for.body.preheader.new ], [ %niter.next.3, %for.body ]
- %7 = trunc nuw nsw i64 %indvars.iv to i32
- %rem = urem i32 %7, 10
- %idx.ext = zext nneg i32 %rem to i64
- %add.ptr2 = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext
- %8 = load i32, ptr %add.ptr2, align 4, !tbaa !4
- %arrayidx = getelementptr inbounds i32, ptr %0, i64 %indvars.iv
- store i32 %8, ptr %arrayidx, align 8, !tbaa !4
- %indvars.iv.next = or disjoint i64 %indvars.iv, 1
- %9 = trunc nuw nsw i64 %indvars.iv.next to i32
- %rem.1 = urem i32 %9, 10
- %idx.ext.1 = zext nneg i32 %rem.1 to i64
- %add.ptr2.1 = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext.1
- %10 = load i32, ptr %add.ptr2.1, align 4, !tbaa !4
- %arrayidx.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next
- store i32 %10, ptr %arrayidx.1, align 4, !tbaa !4
- %indvars.iv.next.1 = or disjoint i64 %indvars.iv, 2
- %11 = trunc nuw nsw i64 %indvars.iv.next.1 to i32
- %rem.2 = urem i32 %11, 10
- %idx.ext.2 = zext nneg i32 %rem.2 to i64
- %add.ptr2.2 = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext.2
- %12 = load i32, ptr %add.ptr2.2, align 4, !tbaa !4
- %arrayidx.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.1
- store i32 %12, ptr %arrayidx.2, align 8, !tbaa !4
- %indvars.iv.next.2 = or disjoint i64 %indvars.iv, 3
- %13 = trunc nuw nsw i64 %indvars.iv.next.2 to i32
- %rem.3 = urem i32 %13, 10
- %idx.ext.3 = zext nneg i32 %rem.3 to i64
- %add.ptr2.3 = getelementptr inbounds i32, ptr %add.ptr, i64 %idx.ext.3
- %14 = load i32, ptr %add.ptr2.3, align 4, !tbaa !4
- %arrayidx.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next.2
- store i32 %14, ptr %arrayidx.3, align 4, !tbaa !4
- %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
- %niter.next.3 = add i64 %niter, 4
- %niter.ncmp.3 = icmp eq i64 %niter.next.3, %unroll_iter
- br i1 %niter.ncmp.3, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body, !llvm.loop !11
+ %2 = zext nneg i32 %len to i64
+ %3 = shl nuw nsw i64 %2, 2
+ call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 8 %0, ptr align 4 %add.ptr, i64 %3, i1 false), !tbaa !5
+ br label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.body.preheader, %entry
+ %4 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %4, 0
+ br i1 %cmp3, label %if.then, label %if.else36
if.then: ; preds = %for.cond.cleanup
- %puts67 = call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
- %15 = call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
- %cmp5 = icmp eq i32 %15, 0
- br i1 %cmp5, label %if.then6, label %if.else
-
-if.then6: ; preds = %if.then
- %puts69 = call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
- call void @func4()
+ %puts73 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ %5 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %5, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts75 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ tail call void @func4()
unreachable
if.else: ; preds = %if.then
- %puts68 = call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
- %16 = load i32, ptr %add.ptr, align 4, !tbaa !4
- %call9 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %16)
- %17 = load i32, ptr %len, align 4, !tbaa !4
- %cmp1274 = icmp sgt i32 %17, 0
- br i1 %cmp1274, label %for.body14, label %for.cond.cleanup13
-
-for.cond.cleanup13: ; preds = %for.body14, %if.else
- %18 = call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #5, !srcloc !13
- %add.ptr21 = getelementptr inbounds i8, ptr %18, i64 8
- %19 = load i32, ptr %len, align 4, !tbaa !4
- %cmp2476 = icmp sgt i32 %19, 0
- br i1 %cmp2476, label %for.body26.preheader, label %for.cond.cleanup25
-
-for.body26.preheader: ; preds = %for.cond.cleanup13
- %wide.trip.count88 = zext nneg i32 %19 to i64
- %xtraiter90 = and i64 %wide.trip.count88, 3
- %20 = icmp ult i32 %19, 4
- br i1 %20, label %for.cond.cleanup25.loopexit.unr-lcssa, label %for.body26.preheader.new
-
-for.body26.preheader.new: ; preds = %for.body26.preheader
- %unroll_iter93 = and i64 %wide.trip.count88, 2147483644
- br label %for.body26
-
-for.body14: ; preds = %if.else, %for.body14
- %indvars.iv82 = phi i64 [ %indvars.iv.next83, %for.body14 ], [ 0, %if.else ]
- %arrayidx16 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv82
- %21 = load i32, ptr %arrayidx16, align 4, !tbaa !4
- %call17 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %21)
- %indvars.iv.next83 = add nuw nsw i64 %indvars.iv82, 1
- %22 = load i32, ptr %len, align 4, !tbaa !4
- %23 = sext i32 %22 to i64
- %cmp12 = icmp slt i64 %indvars.iv.next83, %23
- br i1 %cmp12, label %for.body14, label %for.cond.cleanup13, !llvm.loop !14
-
-for.cond.cleanup25.loopexit.unr-lcssa: ; preds = %for.body26, %for.body26.preheader
- %indvars.iv85.unr = phi i64 [ 0, %for.body26.preheader ], [ %indvars.iv.next86.3, %for.body26 ]
- %lcmp.mod92.not = icmp eq i64 %xtraiter90, 0
- br i1 %lcmp.mod92.not, label %for.cond.cleanup25, label %for.body26.epil
-
-for.body26.epil: ; preds = %for.cond.cleanup25.loopexit.unr-lcssa, %for.body26.epil
- %indvars.iv85.epil = phi i64 [ %indvars.iv.next86.epil, %for.body26.epil ], [ %indvars.iv85.unr, %for.cond.cleanup25.loopexit.unr-lcssa ]
- %epil.iter91 = phi i64 [ %epil.iter91.next, %for.body26.epil ], [ 0, %for.cond.cleanup25.loopexit.unr-lcssa ]
- %24 = trunc nuw nsw i64 %indvars.iv85.epil to i32
- %rem27.epil = urem i32 %24, 10
- %idx.ext28.epil = zext nneg i32 %rem27.epil to i64
- %add.ptr29.epil = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28.epil
- %25 = load i32, ptr %add.ptr29.epil, align 4, !tbaa !4
- %arrayidx31.epil = getelementptr inbounds i32, ptr %0, i64 %indvars.iv85.epil
- store i32 %25, ptr %arrayidx31.epil, align 4, !tbaa !4
- %indvars.iv.next86.epil = add nuw nsw i64 %indvars.iv85.epil, 1
- %epil.iter91.next = add i64 %epil.iter91, 1
- %epil.iter91.cmp.not = icmp eq i64 %epil.iter91.next, %xtraiter90
- br i1 %epil.iter91.cmp.not, label %for.cond.cleanup25, label %for.body26.epil, !llvm.loop !15
-
-for.cond.cleanup25: ; preds = %for.cond.cleanup25.loopexit.unr-lcssa, %for.body26.epil, %for.cond.cleanup13
- call void @func3()
+ %puts74 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %6 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %6)
+ br i1 %cmp76, label %for.body16.preheader, label %for.cond.cleanup15.thread
+
+for.cond.cleanup15.thread: ; preds = %if.else
+ %7 = tail call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #4, !srcloc !9
+ br label %for.cond.cleanup27
+
+for.body16.preheader: ; preds = %if.else
+ %wide.trip.count89 = zext nneg i32 %len to i64
+ br label %for.body16
+
+for.cond.cleanup15: ; preds = %for.body16
+ %8 = tail call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #4, !srcloc !9
+ br label %for.cond.cleanup27
+
+for.body16: ; preds = %for.body16.preheader, %for.body16
+ %indvars.iv86 = phi i64 [ 0, %for.body16.preheader ], [ %indvars.iv.next87, %for.body16 ]
+ %arrayidx18 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv86
+ %9 = load i32, ptr %arrayidx18, align 4, !tbaa !5
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %9)
+ %indvars.iv.next87 = add nuw nsw i64 %indvars.iv86, 1
+ %exitcond90.not = icmp eq i64 %indvars.iv.next87, %wide.trip.count89
+ br i1 %exitcond90.not, label %for.cond.cleanup15, label %for.body16, !llvm.loop !10
+
+for.cond.cleanup27: ; preds = %for.cond.cleanup15, %for.cond.cleanup15.thread
+ tail call void @func3()
unreachable
-for.body26: ; preds = %for.body26, %for.body26.preheader.new
- %indvars.iv85 = phi i64 [ 0, %for.body26.preheader.new ], [ %indvars.iv.next86.3, %for.body26 ]
- %niter94 = phi i64 [ 0, %for.body26.preheader.new ], [ %niter94.next.3, %for.body26 ]
- %26 = trunc nuw nsw i64 %indvars.iv85 to i32
- %rem27 = urem i32 %26, 10
- %idx.ext28 = zext nneg i32 %rem27 to i64
- %add.ptr29 = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28
- %27 = load i32, ptr %add.ptr29, align 4, !tbaa !4
- %arrayidx31 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv85
- store i32 %27, ptr %arrayidx31, align 8, !tbaa !4
- %indvars.iv.next86 = or disjoint i64 %indvars.iv85, 1
- %28 = trunc nuw nsw i64 %indvars.iv.next86 to i32
- %rem27.1 = urem i32 %28, 10
- %idx.ext28.1 = zext nneg i32 %rem27.1 to i64
- %add.ptr29.1 = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28.1
- %29 = load i32, ptr %add.ptr29.1, align 4, !tbaa !4
- %arrayidx31.1 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next86
- store i32 %29, ptr %arrayidx31.1, align 4, !tbaa !4
- %indvars.iv.next86.1 = or disjoint i64 %indvars.iv85, 2
- %30 = trunc nuw nsw i64 %indvars.iv.next86.1 to i32
- %rem27.2 = urem i32 %30, 10
- %idx.ext28.2 = zext nneg i32 %rem27.2 to i64
- %add.ptr29.2 = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28.2
- %31 = load i32, ptr %add.ptr29.2, align 4, !tbaa !4
- %arrayidx31.2 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next86.1
- store i32 %31, ptr %arrayidx31.2, align 8, !tbaa !4
- %indvars.iv.next86.2 = or disjoint i64 %indvars.iv85, 3
- %32 = trunc nuw nsw i64 %indvars.iv.next86.2 to i32
- %rem27.3 = urem i32 %32, 10
- %idx.ext28.3 = zext nneg i32 %rem27.3 to i64
- %add.ptr29.3 = getelementptr inbounds i32, ptr %add.ptr21, i64 %idx.ext28.3
- %33 = load i32, ptr %add.ptr29.3, align 4, !tbaa !4
- %arrayidx31.3 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv.next86.2
- store i32 %33, ptr %arrayidx31.3, align 4, !tbaa !4
- %indvars.iv.next86.3 = add nuw nsw i64 %indvars.iv85, 4
- %niter94.next.3 = add i64 %niter94, 4
- %niter94.ncmp.3 = icmp eq i64 %niter94.next.3, %unroll_iter93
- br i1 %niter94.ncmp.3, label %for.cond.cleanup25.loopexit.unr-lcssa, label %for.body26, !llvm.loop !16
-
-if.else35: ; preds = %for.cond.cleanup
- %puts = call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
- %34 = load i32, ptr %add.ptr, align 4, !tbaa !4
- %call37 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.11, i32 noundef signext %34)
- %35 = load i32, ptr %len, align 4, !tbaa !4
- %cmp4072 = icmp sgt i32 %35, 0
- br i1 %cmp4072, label %for.body42, label %for.cond.cleanup41
-
-for.cond.cleanup41: ; preds = %for.body42, %if.else35
- call void @func2()
- unreachable
+if.else36: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %10 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call38 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %10)
+ br i1 %cmp76, label %for.body44.preheader, label %for.cond.cleanup43
-for.body42: ; preds = %if.else35, %for.body42
- %indvars.iv79 = phi i64 [ %indvars.iv.next80, %for.body42 ], [ 0, %if.else35 ]
- %arrayidx44 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv79
- %36 = load i32, ptr %arrayidx44, align 4, !tbaa !4
- %call45 = call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %36)
- %indvars.iv.next80 = add nuw nsw i64 %indvars.iv79, 1
- %37 = load i32, ptr %len, align 4, !tbaa !4
- %38 = sext i32 %37 to i64
- %cmp40 = icmp slt i64 %indvars.iv.next80, %38
- br i1 %cmp40, label %for.body42, label %for.cond.cleanup41, !llvm.loop !17
-}
+for.body44.preheader: ; preds = %if.else36
+ %wide.trip.count = zext nneg i32 %len to i64
+ br label %for.body44
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
-declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4
+for.cond.cleanup43: ; preds = %for.body44, %if.else36
+ tail call void @func2()
+ unreachable
-; Function Attrs: nofree nounwind
-declare noundef signext i32 @__isoc99_scanf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+for.body44: ; preds = %for.body44.preheader, %for.body44
+ %indvars.iv = phi i64 [ 0, %for.body44.preheader ], [ %indvars.iv.next, %for.body44 ]
+ %arrayidx46 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv
+ %11 = load i32, ptr %arrayidx46, align 4, !tbaa !5
+ %call47 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %11)
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
+ br i1 %exitcond.not, label %for.cond.cleanup43, label %for.body44, !llvm.loop !12
+}
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
; Function Attrs: nounwind
-define dso_local noundef signext i32 @main() local_unnamed_addr #6 {
+define dso_local signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readonly %argv) local_unnamed_addr #5 {
entry:
- %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
- %cmp = icmp eq i32 %0, 0
- br i1 %cmp, label %if.then, label %if.else
-
-if.then: ; preds = %entry
- %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.21)
- %call1 = tail call signext i32 @func1()
+ %cmp = icmp slt i32 %argc, 2
+ br i1 %cmp, label %return, label %if.end
+
+if.end: ; preds = %entry
+ %arrayidx = getelementptr inbounds i8, ptr %argv, i64 8
+ %0 = load ptr, ptr %arrayidx, align 8, !tbaa !13
+ %call.i = tail call i64 @strtol(ptr nocapture noundef nonnull %0, ptr noundef null, i32 noundef signext 10) #4
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp3 = icmp eq i32 %1, 0
+ br i1 %cmp3, label %if.then4, label %return
+
+if.then4: ; preds = %if.end
+ %conv.i = trunc i64 %call.i to i32
+ %cond = tail call i32 @llvm.smin.i32(i32 %conv.i, i32 10)
+ %puts11 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.20)
+ %call6 = tail call signext i32 @func1(i32 noundef signext %cond)
unreachable
-if.else: ; preds = %entry
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.20)
- ret i32 0
+return: ; preds = %if.end, %entry
+ %str.19.sink = phi ptr [ @str.21, %entry ], [ @str.19, %if.end ]
+ %retval.0 = phi i32 [ 1, %entry ], [ 0, %if.end ]
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) %str.19.sink)
+ ret i32 %retval.0
}
+; Function Attrs: mustprogress nofree nounwind willreturn
+declare i64 @strtol(ptr noundef readonly, ptr nocapture noundef, i32 noundef signext) local_unnamed_addr #6
+
; Function Attrs: nofree nounwind
declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare i32 @llvm.smin.i32(i32, i32) #8
+
+; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #9
+
attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #2 = { noreturn nounwind }
attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #4 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-attributes #5 = { nounwind }
-attributes #6 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { mustprogress nofree nounwind willreturn "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #7 = { nofree nounwind }
+attributes #8 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #9 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -399,18 +277,15 @@ attributes #7 = { nofree nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
-!4 = !{!5, !5, i64 0}
-!5 = !{!"int", !6, i64 0}
-!6 = !{!"omnipotent char", !7, i64 0}
-!7 = !{!"Simple C/C++ TBAA"}
-!8 = !{i64 1738}
-!9 = distinct !{!9, !10}
-!10 = !{!"llvm.loop.unroll.disable"}
-!11 = distinct !{!11, !12}
-!12 = !{!"llvm.loop.mustprogress"}
-!13 = !{i64 2419}
-!14 = distinct !{!14, !12}
-!15 = distinct !{!15, !10}
-!16 = distinct !{!16, !12}
-!17 = distinct !{!17, !12}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
+!4 = !{i64 1669}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
+!9 = !{i64 2347}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
+!13 = !{!14, !14, i64 0}
+!14 = !{!"any pointer", !7, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-04.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-04.ll
new file mode 100644
index 00000000000000..3a15262d3e5f68
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-04.ll
@@ -0,0 +1,264 @@
+; Test output for inline Literal Pool with switch statement.
+; len of malloc is global variable.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-04.c'
+source_filename = "builtin-setjmp-longjmp-literal-pool-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".LC202:"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at len = dso_local local_unnamed_addr global i32 10, align 4
+ at .str.6 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.13 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.15 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.17 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.18 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: In func4
+; CHECK: Returned from func4
+; CHECK: value_ptr : 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+; CHECK: In func3
+; CHECK: Returned from func3
+; CHECK: value_ptr: 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+
+ %0 = load i32, ptr @len, align 4, !tbaa !4
+ %conv = sext i32 %0 to i64
+ %mul = shl nsw i64 %conv, 2
+ %1 = alloca i8, i64 %mul, align 8
+ %2 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #4, !srcloc !8
+ %add.ptr = getelementptr i8, ptr %2, i64 8
+ %3 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp72 = icmp sgt i32 %3, 0
+ br i1 %cmp72, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %4 = zext nneg i32 %3 to i64
+ %5 = shl nuw nsw i64 %4, 2
+ call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 8 %1, ptr align 4 %add.ptr, i64 %5, i1 false), !tbaa !4
+ br label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.body.preheader, %entry
+ %6 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %6, 0
+ br i1 %cmp3, label %if.then, label %if.else36
+
+if.then: ; preds = %for.cond.cleanup
+ %puts69 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %7 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %7, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts71 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts70 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ %8 = load i32, ptr %add.ptr, align 4, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %8)
+ %9 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp1376 = icmp sgt i32 %9, 0
+ br i1 %cmp1376, label %for.body16, label %for.cond.cleanup15
+
+for.cond.cleanup15: ; preds = %for.body16, %if.else
+ %10 = tail call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #4, !srcloc !9
+ tail call void @func3()
+ unreachable
+
+for.body16: ; preds = %if.else, %for.body16
+ %indvars.iv82 = phi i64 [ %indvars.iv.next83, %for.body16 ], [ 0, %if.else ]
+ %arrayidx18 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv82
+ %11 = load i32, ptr %arrayidx18, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %11)
+ %indvars.iv.next83 = add nuw nsw i64 %indvars.iv82, 1
+ %12 = load i32, ptr @len, align 4, !tbaa !4
+ %13 = sext i32 %12 to i64
+ %cmp13 = icmp slt i64 %indvars.iv.next83, %13
+ br i1 %cmp13, label %for.body16, label %for.cond.cleanup15, !llvm.loop !10
+
+if.else36: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %14 = load i32, ptr %add.ptr, align 4, !tbaa !4
+ %call38 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %14)
+ %15 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp4174 = icmp sgt i32 %15, 0
+ br i1 %cmp4174, label %for.body44, label %for.cond.cleanup43
+
+for.cond.cleanup43: ; preds = %for.body44, %if.else36
+ tail call void @func2()
+ unreachable
+
+for.body44: ; preds = %if.else36, %for.body44
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.body44 ], [ 0, %if.else36 ]
+ %arrayidx46 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv
+ %16 = load i32, ptr %arrayidx46, align 4, !tbaa !4
+ %call47 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %16)
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %17 = load i32, ptr @len, align 4, !tbaa !4
+ %18 = sext i32 %17 to i64
+ %cmp41 = icmp slt i64 %indvars.iv.next, %18
+ br i1 %cmp41, label %for.body44, label %for.cond.cleanup43, !llvm.loop !12
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #7
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+attributes #7 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = !{i64 1677}
+!9 = !{i64 2355}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-00.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-00.ll
index 402f3c89ac6714..b42cbae8861b64 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-00.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-00.ll
@@ -1,6 +1,6 @@
-; -mbackchain option
-; Test output for inline Literal Pool.
-; RUN: clang -mbackchain -o %t %s
+; Test output(simulating inline Literal Pool).
+
+; RUN: clang -mbackchain -O2 -o %t %s
; RUN: %t | FileCheck %s
; CHECK: value_ptr is 954219
; CHECK: value_ptr is 954219
@@ -86,7 +86,7 @@ attributes #4 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-p
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
!4 = !{i64 751}
!5 = !{!6, !6, i64 0}
!6 = !{!"int", !7, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-01.ll
new file mode 100644
index 00000000000000..45907d672ff289
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-01.ll
@@ -0,0 +1,175 @@
+; Test the output with -mbackchain option.
+
+; The behavior of local variables between setjmp and longjmp in C is undefined.
+; This means that the C standard does not guarantee what will happen
+; to their values.
+
+; Output from gcc at all optimization levels or clang -O0 is:
+
+;First __builtin_setjmp in func1
+;Second __builtin_setjmp in func1
+;Returned from func4
+;value_ptr : 954219
+;Returned from func3
+;value_ptr: 420420
+
+; RUN: clang -O2 -mbackchain -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-01.c'
+source_filename = "builtin-setjmp-longjmp-literal-pool-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.13 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.14 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.15 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.16 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.17 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.18 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: value_ptr : 954219
+; CHECK: Returned from func3
+; CHECK: value_ptr: 954219
+
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+ %0 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #4, !srcloc !4
+ %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp = icmp eq i32 %1, 0
+ br i1 %cmp, label %if.then, label %if.else7
+
+if.then: ; preds = %entry
+ %puts13 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp1 = icmp eq i32 %2, 0
+ br i1 %cmp1, label %if.then2, label %if.else
+
+if.then2: ; preds = %if.then
+ %puts15 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts14 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %3 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %3)
+ tail call void @func3()
+ unreachable
+
+if.else7: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %4 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.8, i32 noundef signext %4)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
+!4 = !{i64 1166}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-02.ll
new file mode 100644
index 00000000000000..868ef843a4f702
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-02.ll
@@ -0,0 +1,277 @@
+; Test the output with -mbackchain option.
+
+; The behavior of local variables between setjmp and longjmp in C is undefined.
+; This means that the C standard does not guarantee what will happen
+; to their values.
+
+; Output from gcc at all optimization levels or clang -O0 is:
+
+;First __builtin_setjmp in func1
+;Second __builtin_setjmp in func1
+;Returned from func4
+;value_ptr : 954219
+;arr: 954219
+;arr: 466232
+;arr: 955551
+;arr: 687823
+;arr: 555123
+;arr: 777723
+;arr: 985473
+;arr: 190346
+;arr: 420420
+;arr: 732972
+;Returned from func3
+;value_ptr: 971166
+;arr: 971166
+;arr: 123454
+;arr: 451233
+;arr: 954219
+;arr: 466232
+;arr: 955551
+;arr: 687823
+;arr: 555123
+;arr: 123454
+;arr: 451233
+
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-02.c'
+source_filename = "builtin-setjmp-longjmp-literal-pool-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".LC202:"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.13 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.15 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.17 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.18 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+
+; CHECK: Returned from func4
+; CHECK: value_ptr : 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+; CHECK: Returned from func3
+; CHECK: value_ptr: 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+
+ %0 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #4, !srcloc !4
+ %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
+ %.sroa.0.0.copyload = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %.sroa.4.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 12
+ %.sroa.4.0.copyload = load i32, ptr %.sroa.4.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.6.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 16
+ %.sroa.6.0.copyload = load i32, ptr %.sroa.6.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.8.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 20
+ %.sroa.8.0.copyload = load i32, ptr %.sroa.8.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.10.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 24
+ %.sroa.10.0.copyload = load i32, ptr %.sroa.10.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.12.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 28
+ %.sroa.12.0.copyload = load i32, ptr %.sroa.12.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.14.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 32
+ %.sroa.14.0.copyload = load i32, ptr %.sroa.14.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.16.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 36
+ %.sroa.16.0.copyload = load i32, ptr %.sroa.16.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.18.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 40
+ %.sroa.18.0.copyload = load i32, ptr %.sroa.18.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %.sroa.20.0.add.ptr.sroa_idx = getelementptr inbounds i8, ptr %0, i64 44
+ %.sroa.20.0.copyload = load i32, ptr %.sroa.20.0.add.ptr.sroa_idx, align 4, !tbaa !5
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp2 = icmp eq i32 %1, 0
+ br i1 %cmp2, label %if.then, label %if.else32
+
+if.then: ; preds = %entry
+ %puts64 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp3 = icmp eq i32 %2, 0
+ br i1 %cmp3, label %if.then4, label %if.else
+
+if.then4: ; preds = %if.then
+ %puts66 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts65 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ %3 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %3)
+ %call15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.0.0.copyload)
+ %call15.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.4.0.copyload)
+ %call15.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.6.0.copyload)
+ %call15.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.8.0.copyload)
+ %call15.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.10.0.copyload)
+ %call15.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.12.0.copyload)
+ %call15.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.14.0.copyload)
+ %call15.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.16.0.copyload)
+ %call15.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.18.0.copyload)
+ %call15.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.20.0.copyload)
+ %4 = tail call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #4, !srcloc !9
+ tail call void @func3()
+ unreachable
+
+if.else32: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %5 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call34 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %5)
+ %call42 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.0.0.copyload)
+ %call42.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.4.0.copyload)
+ %call42.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.6.0.copyload)
+ %call42.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.8.0.copyload)
+ %call42.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.10.0.copyload)
+ %call42.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.12.0.copyload)
+ %call42.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.14.0.copyload)
+ %call42.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.16.0.copyload)
+ %call42.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.18.0.copyload)
+ %call42.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %.sroa.20.0.copyload)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
+!4 = !{i64 1661}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
+!9 = !{i64 2337}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-03.ll
new file mode 100644
index 00000000000000..75e7985b2ac948
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-03.ll
@@ -0,0 +1,290 @@
+; -mbackchain option
+; Test output for inline Literal Pool with switch statement.
+; len of malloc is passed as argument.
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t 10 | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-03.c'
+source_filename = "builtin-setjmp-longjmp-literal-pool-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".LC202:"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.13 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.14 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.15 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.16 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.18 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.19 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.20 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+ at str.21 = private unnamed_addr constant [30 x i8] c"Usage: program_name <length> \00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1(i32 noundef signext %len) local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: In func4
+; CHECK: Returned from func4
+; CHECK: value_ptr : 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+; CHECK: In func3
+; CHECK: Returned from func3
+; CHECK: value_ptr: 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+
+ %conv = sext i32 %len to i64
+ %mul = shl nsw i64 %conv, 2
+ %0 = alloca i8, i64 %mul, align 8
+ %1 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #4, !srcloc !4
+ %add.ptr = getelementptr i8, ptr %1, i64 8
+ %cmp76 = icmp sgt i32 %len, 0
+ br i1 %cmp76, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %2 = zext nneg i32 %len to i64
+ %3 = shl nuw nsw i64 %2, 2
+ call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 8 %0, ptr align 4 %add.ptr, i64 %3, i1 false), !tbaa !5
+ br label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.body.preheader, %entry
+ %4 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %4, 0
+ br i1 %cmp3, label %if.then, label %if.else36
+
+if.then: ; preds = %for.cond.cleanup
+ %puts73 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ %5 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %5, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts75 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts74 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %6 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %6)
+ br i1 %cmp76, label %for.body16.preheader, label %for.cond.cleanup15.thread
+
+for.cond.cleanup15.thread: ; preds = %if.else
+ %7 = tail call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #4, !srcloc !9
+ br label %for.cond.cleanup27
+
+for.body16.preheader: ; preds = %if.else
+ %wide.trip.count89 = zext nneg i32 %len to i64
+ br label %for.body16
+
+for.cond.cleanup15: ; preds = %for.body16
+ %8 = tail call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #4, !srcloc !9
+ br label %for.cond.cleanup27
+
+for.body16: ; preds = %for.body16.preheader, %for.body16
+ %indvars.iv86 = phi i64 [ 0, %for.body16.preheader ], [ %indvars.iv.next87, %for.body16 ]
+ %arrayidx18 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv86
+ %9 = load i32, ptr %arrayidx18, align 4, !tbaa !5
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %9)
+ %indvars.iv.next87 = add nuw nsw i64 %indvars.iv86, 1
+ %exitcond90.not = icmp eq i64 %indvars.iv.next87, %wide.trip.count89
+ br i1 %exitcond90.not, label %for.cond.cleanup15, label %for.body16, !llvm.loop !10
+
+for.cond.cleanup27: ; preds = %for.cond.cleanup15, %for.cond.cleanup15.thread
+ tail call void @func3()
+ unreachable
+
+if.else36: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %10 = load i32, ptr %add.ptr, align 4, !tbaa !5
+ %call38 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %10)
+ br i1 %cmp76, label %for.body44.preheader, label %for.cond.cleanup43
+
+for.body44.preheader: ; preds = %if.else36
+ %wide.trip.count = zext nneg i32 %len to i64
+ br label %for.body44
+
+for.cond.cleanup43: ; preds = %for.body44, %if.else36
+ tail call void @func2()
+ unreachable
+
+for.body44: ; preds = %for.body44.preheader, %for.body44
+ %indvars.iv = phi i64 [ 0, %for.body44.preheader ], [ %indvars.iv.next, %for.body44 ]
+ %arrayidx46 = getelementptr inbounds i32, ptr %0, i64 %indvars.iv
+ %11 = load i32, ptr %arrayidx46, align 4, !tbaa !5
+ %call47 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %11)
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
+ br i1 %exitcond.not, label %for.cond.cleanup43, label %for.body44, !llvm.loop !12
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readonly %argv) local_unnamed_addr #5 {
+entry:
+ %cmp = icmp slt i32 %argc, 2
+ br i1 %cmp, label %return, label %if.end
+
+if.end: ; preds = %entry
+ %arrayidx = getelementptr inbounds i8, ptr %argv, i64 8
+ %0 = load ptr, ptr %arrayidx, align 8, !tbaa !13
+ %call.i = tail call i64 @strtol(ptr nocapture noundef nonnull %0, ptr noundef null, i32 noundef signext 10) #4
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp3 = icmp eq i32 %1, 0
+ br i1 %cmp3, label %if.then4, label %return
+
+if.then4: ; preds = %if.end
+ %conv.i = trunc i64 %call.i to i32
+ %cond = tail call i32 @llvm.smin.i32(i32 %conv.i, i32 10)
+ %puts11 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.20)
+ %call6 = tail call signext i32 @func1(i32 noundef signext %cond)
+ unreachable
+
+return: ; preds = %if.end, %entry
+ %str.19.sink = phi ptr [ @str.21, %entry ], [ @str.19, %if.end ]
+ %retval.0 = phi i32 [ 1, %entry ], [ 0, %if.end ]
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) %str.19.sink)
+ ret i32 %retval.0
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn
+declare i64 @strtol(ptr noundef readonly, ptr nocapture noundef, i32 noundef signext) local_unnamed_addr #6
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare i32 @llvm.smin.i32(i32, i32) #8
+
+; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #9
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { mustprogress nofree nounwind willreturn "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+attributes #8 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+attributes #9 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
+!4 = !{i64 1669}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"int", !7, i64 0}
+!7 = !{!"omnipotent char", !8, i64 0}
+!8 = !{!"Simple C/C++ TBAA"}
+!9 = !{i64 2347}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
+!13 = !{!14, !14, i64 0}
+!14 = !{!"any pointer", !7, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-04.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-04.ll
new file mode 100644
index 00000000000000..f469855f0c1e95
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-literal-pool-backchain-04.ll
@@ -0,0 +1,264 @@
+; -mbackchain option
+; Test output for inline Literal Pool with switch statement.
+; len of malloc is global variable.
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-literal-pool-04.c'
+source_filename = "builtin-setjmp-longjmp-literal-pool-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+module asm ".LC101:"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".LC202:"
+module asm ".long 420420"
+module asm ".long 732972"
+module asm ".long 971166"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 123454"
+module asm ".long 451233"
+module asm ".long 954219"
+module asm ".long 466232"
+module asm ".long 955551"
+module asm ".long 687823"
+module asm ".long 555123"
+module asm ".long 777723"
+module asm ".long 985473"
+module asm ".long 190346"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at len = dso_local local_unnamed_addr global i32 10, align 4
+ at .str.6 = private unnamed_addr constant [16 x i8] c"value_ptr : %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [15 x i8] c"value_ptr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.12 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.13 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.15 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.17 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.18 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.19 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: In func4
+; CHECK: Returned from func4
+; CHECK: value_ptr : 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+; CHECK: In func3
+; CHECK: Returned from func3
+; CHECK: value_ptr: 954219
+; CHECK: arr: 954219
+; CHECK: arr: 466232
+; CHECK: arr: 955551
+; CHECK: arr: 687823
+; CHECK: arr: 555123
+; CHECK: arr: 777723
+; CHECK: arr: 985473
+; CHECK: arr: 190346
+; CHECK: arr: 420420
+; CHECK: arr: 732972
+
+ %0 = load i32, ptr @len, align 4, !tbaa !4
+ %conv = sext i32 %0 to i64
+ %mul = shl nsw i64 %conv, 2
+ %1 = alloca i8, i64 %mul, align 8
+ %2 = tail call ptr asm sideeffect "larl $0, .LC101", "={r13}"() #4, !srcloc !8
+ %add.ptr = getelementptr i8, ptr %2, i64 8
+ %3 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp72 = icmp sgt i32 %3, 0
+ br i1 %cmp72, label %for.body.preheader, label %for.cond.cleanup
+
+for.body.preheader: ; preds = %entry
+ %4 = zext nneg i32 %3 to i64
+ %5 = shl nuw nsw i64 %4, 2
+ call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 8 %1, ptr align 4 %add.ptr, i64 %5, i1 false), !tbaa !4
+ br label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.body.preheader, %entry
+ %6 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %6, 0
+ br i1 %cmp3, label %if.then, label %if.else36
+
+if.then: ; preds = %for.cond.cleanup
+ %puts69 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ %7 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %7, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts71 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts70 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ %8 = load i32, ptr %add.ptr, align 4, !tbaa !4
+ %call10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %8)
+ %9 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp1376 = icmp sgt i32 %9, 0
+ br i1 %cmp1376, label %for.body16, label %for.cond.cleanup15
+
+for.cond.cleanup15: ; preds = %for.body16, %if.else
+ %10 = tail call ptr asm sideeffect "larl $0, .LC202", "={r13}"() #4, !srcloc !9
+ tail call void @func3()
+ unreachable
+
+for.body16: ; preds = %if.else, %for.body16
+ %indvars.iv82 = phi i64 [ %indvars.iv.next83, %for.body16 ], [ 0, %if.else ]
+ %arrayidx18 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv82
+ %11 = load i32, ptr %arrayidx18, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %11)
+ %indvars.iv.next83 = add nuw nsw i64 %indvars.iv82, 1
+ %12 = load i32, ptr @len, align 4, !tbaa !4
+ %13 = sext i32 %12 to i64
+ %cmp13 = icmp slt i64 %indvars.iv.next83, %13
+ br i1 %cmp13, label %for.body16, label %for.cond.cleanup15, !llvm.loop !10
+
+if.else36: ; preds = %for.cond.cleanup
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %14 = load i32, ptr %add.ptr, align 4, !tbaa !4
+ %call38 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.9, i32 noundef signext %14)
+ %15 = load i32, ptr @len, align 4, !tbaa !4
+ %cmp4174 = icmp sgt i32 %15, 0
+ br i1 %cmp4174, label %for.body44, label %for.cond.cleanup43
+
+for.cond.cleanup43: ; preds = %for.body44, %if.else36
+ tail call void @func2()
+ unreachable
+
+for.body44: ; preds = %if.else36, %for.body44
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.body44 ], [ 0, %if.else36 ]
+ %arrayidx46 = getelementptr inbounds i32, ptr %1, i64 %indvars.iv
+ %16 = load i32, ptr %arrayidx46, align 4, !tbaa !4
+ %call47 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.7, i32 noundef signext %16)
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %17 = load i32, ptr @len, align 4, !tbaa !4
+ %18 = sext i32 %17 to i64
+ %cmp41 = icmp slt i64 %indvars.iv.next, %18
+ br i1 %cmp41, label %for.body44, label %for.cond.cleanup43, !llvm.loop !12
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.19)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.18)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #7
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+attributes #7 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git b289df99d26b008287e18cdb0858bc569de3f2ad)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = !{i64 1677}
+!9 = !{i64 2355}
+!10 = distinct !{!10, !11}
+!11 = !{!"llvm.loop.mustprogress"}
+!12 = distinct !{!12, !11}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll
index 2c45c5cc089ac7..a04a7893eb7d60 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-01.ll
@@ -1,7 +1,7 @@
; Inducing double register pressure.
; Test output of setjmp/longjmp with 20 global double variable
; sum(regsiter pressure).
-; RUN: clang -o %t %s
+; RUN: clang -O2 -o %t %s
; RUN: %t | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-double-01.c'
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll
index 2ef58fabe342e3..c68fe98c2ad015 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-02.ll
@@ -6,7 +6,7 @@
; Stack Pointer in slot 4.
; Clobber %r6-%r15, %f8-%f15.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-double-02.c'
source_filename = "builtin-setjmp-spills-double-02.c"
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll
index 2637bda4c67eb5..4a1ce2741bfae7 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-03.ll
@@ -7,7 +7,7 @@
; Stack Pointer in slot 4.
; Clobber %r6-%r15, %f8-%f15.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-double-03.c'
source_filename = "builtin-setjmp-spills-double-03.c"
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-01.ll
index 4d56a9dd19bbdf..7a4092431db493 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-01.ll
@@ -2,7 +2,7 @@
; Inducing double register pressure.
; Test output of setjmp/longjmp with 20 global double variable
; sum(regsiter pressure).
-; RUN: clang -o %t %s
+; RUN: clang -O2 -o %t %s
; RUN: %t | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-double-01.c'
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-02.ll
index 784a1e3583e7eb..6aa0689a54a3b7 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-02.ll
@@ -7,7 +7,7 @@
; Stack Pointer in slot 4.
; Clobber %r6-%r15, %f8-%f15.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-double-02.c'
source_filename = "builtin-setjmp-spills-double-02.c"
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-03.ll
index 78a6cc784847cc..6ed446f5542ca2 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-double-backchain-03.ll
@@ -8,7 +8,7 @@
; Stack Pointer in slot 4.
; Clobber %r6-%r15, %f8-%f15.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-double-03.c'
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll
index 0a4d115f6d4f55..db0d9df9f1c638 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-01.ll
@@ -1,6 +1,6 @@
; Inducing integer register pressure.
; Test output of setjmp/longjmp with 20 global int variable sum(regsiter pressure).
-; RUN: clang -o %t %s
+; RUN: clang -O2 -o %t %s
; RUN: %t | FileCheck %s
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll
index 3e8bfe81d083b9..8c0b4a3b89c38b 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-02.ll
@@ -6,7 +6,7 @@
; Stack Pointer in slot 4.
; Clobber %r6-%r15, %f8-%f15.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-int-02.c'
source_filename = "builtin-setjmp-spills-int-02.c"
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll
index b84e9a3fc61dd5..43610695dcbbd2 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-03.ll
@@ -7,7 +7,7 @@
; Stack Pointer in slot 4.
; Clobber %r6-%r15, %f8-%f15.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-int-03.c'
source_filename = "builtin-setjmp-spills-int-03.c"
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-01.ll
index 0a51c45173e243..d35a3905d9642f 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-01.ll
@@ -1,5 +1,5 @@
; Test output of setjmp/longjmp with 20 global variable sum(regsiter pressure).
-; RUN: clang -mbackchain -o %t %s
+; RUN: clang -mbackchain -O2 -o %t %s
; RUN: %t | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-int-01.c'
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-02.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-02.ll
index 9c1586e6aaa1b7..5ff933b9b2eda3 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-02.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-02.ll
@@ -8,7 +8,7 @@
; Stack Pointer in slot 4.
; Clobber %r6-%r15, %f8-%f15.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-int-02.c'
source_filename = "builtin-setjmp-spills-int-02.c"
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-03.ll
index e1ece2c3010fa7..7cbc1764cb9e21 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-spills-int-backchain-03.ll
@@ -9,7 +9,7 @@
; Stack Pointer in slot 4.
; Clobber %r6-%r15, %f8-%f15.
-; RUN: llc < %s | FileCheck %s
+; RUN: llc -O2 < %s | FileCheck %s
; ModuleID = 'builtin-setjmp-spills-int-03.c'
source_filename = "builtin-setjmp-spills-int-03.c"
>From fb082f6093d5c58b899bfc4b2373966e38b6e763 Mon Sep 17 00:00:00 2001
From: anoop-kumar6 <anoop.kumar6 at ibm.com>
Date: Sat, 9 Nov 2024 19:14:18 +0100
Subject: [PATCH 7/9] Adding test cases for setjmp/longjmp.
---
.../SystemZ/builtin-setjmp-longjmp-03.ll | 87 ++++
.../SystemZ/builtin-setjmp-longjmp-04-o0.ll | 94 +++++
.../SystemZ/builtin-setjmp-longjmp-04-o2.ll | 93 +++++
.../builtin-setjmp-longjmp-alloca-00-o0.ll | 284 +++++++++++++
.../builtin-setjmp-longjmp-alloca-00-o2.ll | 170 ++++++++
.../builtin-setjmp-longjmp-alloca-00.ll | 35 +-
.../builtin-setjmp-longjmp-alloca-04-o0.ll | 149 +++++++
.../builtin-setjmp-longjmp-alloca-04-o2.ll | 157 +++++++
.../builtin-setjmp-longjmp-alloca-04.ll | 16 +-
...n-setjmp-longjmp-alloca-backchain-00-o0.ll | 286 +++++++++++++
...n-setjmp-longjmp-alloca-backchain-00-o2.ll | 170 ++++++++
...n-setjmp-longjmp-alloca-backchain-04-o0.ll | 150 +++++++
...n-setjmp-longjmp-alloca-backchain-04-o2.ll | 133 ++++++
.../builtin-setjmp-longjmp-backchain-03.ll | 88 ++--
.../builtin-setjmp-longjmp-backchain-04-o0.ll | 95 +++++
.../builtin-setjmp-longjmp-backchain-04-o2.ll | 95 +++++
...ltin-setjmp-longjmp-malloc-global-02-o2.ll | 133 ++++++
...ltin-setjmp-longjmp-malloc-global-0l-o2.ll | 109 +++++
...p-longjmp-malloc-global-backchain-02-o2.ll | 135 ++++++
...p-longjmp-malloc-global-backchain-0l-o2.ll | 111 +++++
...iltin-setjmp-longjmp-malloc-local-01-o0.ll | 105 +++++
...iltin-setjmp-longjmp-malloc-local-02-o0.ll | 147 +++++++
.../builtin-setjmp-longjmp-malloc-local-03.ll | 393 ++++++++++++++++++
...mp-longjmp-malloc-local-backchain-01-o0.ll | 106 +++++
...mp-longjmp-malloc-local-backchain-02-o0.ll | 147 +++++++
...etjmp-longjmp-malloc-local-backchain-03.ll | 393 ++++++++++++++++++
...in-setjmp-longjmp-malloc-volatile-01-o2.ll | 104 +++++
...in-setjmp-longjmp-malloc-volatile-02-o2.ll | 122 ++++++
...longjmp-malloc-volatile-backchain-01-o2.ll | 105 +++++
...longjmp-malloc-volatile-backchain-02-o2.ll | 124 ++++++
30 files changed, 4257 insertions(+), 79 deletions(-)
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-04-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-04-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-00-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-00-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-04-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-04-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-04-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-04-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-02-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-0l-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-backchain-02-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-backchain-0l-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-01-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-02-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-01-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-02-o0.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-03.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-01-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-02-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-backchain-01-o2.ll
create mode 100644 llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-backchain-02-o2.ll
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-03.ll
new file mode 100644
index 00000000000000..ee2a0d84110af8
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-03.ll
@@ -0,0 +1,87 @@
+; This test is intended to test control flow of setjmp/longjmp calls,
+; reachable and unreachabel paths both.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ********** Output should be as follows: ***********
+; CHECK: setjmp has been called
+; CHECK: Calling function foo
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-03.c'
+source_filename = "builtin-setjmp-longjmp-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+ at str.7 = private unnamed_addr constant [23 x i8] c"setjmp has been called\00", align 1
+ at str.8 = private unnamed_addr constant [21 x i8] c"Calling function foo\00", align 1
+ at str.10 = private unnamed_addr constant [24 x i8] c"longjmp has been called\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #1
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #2 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #3 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ br i1 %cmp.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %puts6 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 0) #1
+ unreachable
+
+if.end: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.7)
+ %puts4 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.8)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #5
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { noreturn nounwind }
+attributes #2 = { nofree noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nofree noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-04-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-04-o0.ll
new file mode 100644
index 00000000000000..8841f991776e96
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-04-o0.ll
@@ -0,0 +1,94 @@
+; Tests output of local valiable being modified between setjmp and longjmp call.
+; This test is without optimizations -O0.
+
+; RUN: clang -O0 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ********** Output should be as follows: ***********
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-04.c'
+source_filename = "builtin-setjmp-longjmp-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [42 x i8] c"Calling longjmp from inside function foo\0A\00", align 2
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [29 x i8] c"Performing function recover\0A\00", align 2
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at .str.5 = private unnamed_addr constant [50 x i8] c"This point should never be reached local_var=%d \0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @foo() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @recover() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ ret void
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %local_var = alloca i32, align 4
+ store i32 10, ptr %local_var, align 4
+ %0 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf)
+ %cmp = icmp ne i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %1 = load i32, ptr %local_var, align 4
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef signext %1)
+ call void @recover()
+ call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %2 = load i32, ptr %local_var, align 4
+ %call1 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3, i32 noundef signext %2)
+ store i32 20, ptr %local_var, align 4
+ %3 = load i32, ptr %local_var, align 4
+ %call2 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4, i32 noundef signext %3)
+ call void @foo()
+ %4 = load i32, ptr %local_var, align 4
+ %call3 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5, i32 noundef signext %4)
+ ret i32 0
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: noreturn nounwind
+declare void @exit(i32 noundef signext) #4
+
+attributes #0 = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind }
+attributes #4 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-04-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-04-o2.ll
new file mode 100644
index 00000000000000..05e769526d09a8
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-04-o2.ll
@@ -0,0 +1,93 @@
+; Tests output of local valiable being modified between setjmp and longjmp call.
+; This test output is at -O2 and it does not match the output at -O0.
+; Any modification to non-volatile local variable between setjmp
+; and longjmp calls will not persist.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ********** Output does not match with -O0 Undefined: ***********
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=10
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-04.c'
+source_filename = "builtin-setjmp-longjmp-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ br i1 %cmp.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext 10)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext 10)
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext 20)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #6
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { nounwind }
+attributes #6 = { nofree noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00-o0.ll
new file mode 100644
index 00000000000000..ff044648c5a511
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00-o0.ll
@@ -0,0 +1,284 @@
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is without optimization -O0, modified value persists.
+
+; RUN: clang -O0 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-00.c'
+source_filename = "builtin-setjmp-longjmp-alloca-00.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [10 x i8] c"In func4\0A\00", align 2
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [10 x i8] c"In func3\0A\00", align 2
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [10 x i8] c"In func2\0A\00", align 2
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.3 = private unnamed_addr constant [33 x i8] c"First __builtin_setjmp in func1\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [34 x i8] c"Second __builtin_setjmp in func1\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [21 x i8] c"Returned from func4\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [21 x i8] c"Returned from func3\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [21 x i8] c"In main, first time\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [45 x i8] c"In main, after __builtin_longjmp from func1\0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func4() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf3)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func3() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func2() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf1)
+ unreachable
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @func1() #0 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 3
+; CHECK: arr: 14
+; CHECK: arr: 39
+; CHECK: arr: 84
+; CHECK: arr: 155
+; CHECK: arr: 258
+; CHECK: arr: 399
+; CHECK: arr: 584
+; CHECK: arr: 819
+
+ %len = alloca i32, align 4
+ %arr = alloca ptr, align 8
+ %i = alloca i32, align 4
+ %i10 = alloca i32, align 4
+ %i21 = alloca i32, align 4
+ %i38 = alloca i32, align 4
+ store i32 10, ptr %len, align 4
+ %0 = load i32, ptr %len, align 4
+ %conv = sext i32 %0 to i64
+ %mul = mul i64 %conv, 4
+ %1 = alloca i8, i64 %mul, align 8
+ store ptr %1, ptr %arr, align 8
+ store i32 0, ptr %i, align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %2 = load i32, ptr %i, align 4
+ %3 = load i32, ptr %len, align 4
+ %cmp = icmp slt i32 %2, %3
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %4 = load i32, ptr %i, align 4
+ %5 = load i32, ptr %i, align 4
+ %mul2 = mul nsw i32 %4, %5
+ %6 = load i32, ptr %i, align 4
+ %add = add nsw i32 %mul2, %6
+ %7 = load ptr, ptr %arr, align 8
+ %8 = load i32, ptr %i, align 4
+ %idxprom = sext i32 %8 to i64
+ %arrayidx = getelementptr inbounds i32, ptr %7, i64 %idxprom
+ store i32 %add, ptr %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %9 = load i32, ptr %i, align 4
+ %inc = add nsw i32 %9, 1
+ store i32 %inc, ptr %i, align 4
+ br label %for.cond, !llvm.loop !5
+
+for.end: ; preds = %for.cond
+ %10 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf2)
+ %cmp3 = icmp eq i32 %10, 0
+ br i1 %cmp3, label %if.then, label %if.else36
+
+if.then: ; preds = %for.end
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3)
+ %11 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf3)
+ %cmp5 = icmp eq i32 %11, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %call8 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4)
+ call void @func4()
+ br label %if.end
+
+if.else: ; preds = %if.then
+ %call9 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5)
+ store i32 0, ptr %i10, align 4
+ br label %for.cond11
+
+for.cond11: ; preds = %for.inc18, %if.else
+ %12 = load i32, ptr %i10, align 4
+ %13 = load i32, ptr %len, align 4
+ %cmp12 = icmp slt i32 %12, %13
+ br i1 %cmp12, label %for.body14, label %for.end20
+
+for.body14: ; preds = %for.cond11
+ %14 = load ptr, ptr %arr, align 8
+ %15 = load i32, ptr %i10, align 4
+ %idxprom15 = sext i32 %15 to i64
+ %arrayidx16 = getelementptr inbounds i32, ptr %14, i64 %idxprom15
+ %16 = load i32, ptr %arrayidx16, align 4
+ %call17 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.6, i32 noundef signext %16)
+ br label %for.inc18
+
+for.inc18: ; preds = %for.body14
+ %17 = load i32, ptr %i10, align 4
+ %inc19 = add nsw i32 %17, 1
+ store i32 %inc19, ptr %i10, align 4
+ br label %for.cond11, !llvm.loop !7
+
+for.end20: ; preds = %for.cond11
+ store i32 0, ptr %i21, align 4
+ br label %for.cond22
+
+for.cond22: ; preds = %for.inc33, %for.end20
+ %18 = load i32, ptr %i21, align 4
+ %19 = load i32, ptr %len, align 4
+ %cmp23 = icmp slt i32 %18, %19
+ br i1 %cmp23, label %for.body25, label %for.end35
+
+for.body25: ; preds = %for.cond22
+ %20 = load i32, ptr %i21, align 4
+ %21 = load i32, ptr %i21, align 4
+ %mul26 = mul nsw i32 %20, %21
+ %22 = load i32, ptr %i21, align 4
+ %mul27 = mul nsw i32 %mul26, %22
+ %23 = load i32, ptr %i21, align 4
+ %24 = load i32, ptr %i21, align 4
+ %mul28 = mul nsw i32 %23, %24
+ %add29 = add nsw i32 %mul27, %mul28
+ %25 = load i32, ptr %i21, align 4
+ %add30 = add nsw i32 %add29, %25
+ %26 = load ptr, ptr %arr, align 8
+ %27 = load i32, ptr %i21, align 4
+ %idxprom31 = sext i32 %27 to i64
+ %arrayidx32 = getelementptr inbounds i32, ptr %26, i64 %idxprom31
+ store i32 %add30, ptr %arrayidx32, align 4
+ br label %for.inc33
+
+for.inc33: ; preds = %for.body25
+ %28 = load i32, ptr %i21, align 4
+ %inc34 = add nsw i32 %28, 1
+ store i32 %inc34, ptr %i21, align 4
+ br label %for.cond22, !llvm.loop !8
+
+for.end35: ; preds = %for.cond22
+ call void @func3()
+ br label %if.end
+
+if.end: ; preds = %for.end35, %if.then7
+ br label %if.end49
+
+if.else36: ; preds = %for.end
+ %call37 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.7)
+ store i32 0, ptr %i38, align 4
+ br label %for.cond39
+
+for.cond39: ; preds = %for.inc46, %if.else36
+ %29 = load i32, ptr %i38, align 4
+ %30 = load i32, ptr %len, align 4
+ %cmp40 = icmp slt i32 %29, %30
+ br i1 %cmp40, label %for.body42, label %for.end48
+
+for.body42: ; preds = %for.cond39
+ %31 = load ptr, ptr %arr, align 8
+ %32 = load i32, ptr %i38, align 4
+ %idxprom43 = sext i32 %32 to i64
+ %arrayidx44 = getelementptr inbounds i32, ptr %31, i64 %idxprom43
+ %33 = load i32, ptr %arrayidx44, align 4
+ %call45 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.6, i32 noundef signext %33)
+ br label %for.inc46
+
+for.inc46: ; preds = %for.body42
+ %34 = load i32, ptr %i38, align 4
+ %inc47 = add nsw i32 %34, 1
+ store i32 %inc47, ptr %i38, align 4
+ br label %for.cond39, !llvm.loop !9
+
+for.end48: ; preds = %for.cond39
+ call void @func2()
+ br label %if.end49
+
+if.end49: ; preds = %for.end48, %if.end
+ ret i32 0
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %retval = alloca i32, align 4
+ store i32 0, ptr %retval, align 4
+ %0 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.8)
+ %call1 = call signext i32 @func1()
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call2 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.9)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ ret i32 0
+}
+
+attributes #0 = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!5 = distinct !{!5, !6}
+!6 = !{!"llvm.loop.mustprogress"}
+!7 = distinct !{!7, !6}
+!8 = distinct !{!8, !6}
+!9 = distinct !{!9, !6}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00-o2.ll
new file mode 100644
index 00000000000000..c089281973ad72
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00-o2.ll
@@ -0,0 +1,170 @@
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is with optimization -O2, modified value does not persist.
+; Undefined. Anoop
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-00.c'
+source_filename = "builtin-setjmp-longjmp-alloca-00.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %0, 0
+ br i1 %cmp3, label %if.then, label %if.else38
+
+if.then: ; preds = %entry
+ %puts77 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %1, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts78 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
+ %call18.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
+ %call18.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
+ %call18.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
+ %call18.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
+ %call18.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
+ %call18.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
+ %call18.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
+ %call18.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
+ %call18.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
+ tail call void @func3()
+ unreachable
+
+if.else38: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %call48 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
+ %call48.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
+ %call48.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
+ %call48.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
+ %call48.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
+ %call48.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
+ %call48.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
+ %call48.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
+ %call48.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
+ %call48.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll
index 37f24e7975a6e5..32de8305fb11a9 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-00.ll
@@ -1,34 +1,7 @@
-; This tests Frame Pointer.
-; This test case produces Wrong result when len of malloc is local int variable.
-; But its output is correct when len is global int len, local volatile int len.
-
-; FIXME: Correct Output is:
-;First __builtin_setjmp in func1
-;Second __builtin_setjmp in func1
-;Returned from func4
-;arr: 0
-;arr: 2
-;arr: 6
-;arr: 12
-;arr: 20
-;arr: 30
-;arr: 42
-;arr: 56
-;arr: 72
-;arr: 90
-;Returned from func3
-;arr: 0
-;arr: 3
-;arr: 14
-;arr: 39
-;arr: 84
-;arr: 155
-;arr: 258
-;arr: 399
-;arr: 584
-;arr: 819
-
-; TODO: test case with -mbackchain
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is without optimization -O2, modified value does not persist.
+; Undefined. Anoop
; RUN: clang -O2 -o %t %s
; RUN: %t | FileCheck %s
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04-o0.ll
new file mode 100644
index 00000000000000..642e619e18d170
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04-o0.ll
@@ -0,0 +1,149 @@
+; -mbackchain
+; This tests Frame Pointer.
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is without optimization -O0, modified value persists.
+
+; RUN: clang -mbackchain -O0 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-04.c'
+source_filename = "builtin-setjmp-longjmp-alloca-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [10 x i8] c"In func4\0A\00", align 2
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [10 x i8] c"In func3\0A\00", align 2
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [10 x i8] c"In func2\0A\00", align 2
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.3 = private unnamed_addr constant [33 x i8] c"First __builtin_setjmp in func1\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [34 x i8] c"Second __builtin_setjmp in func1\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [21 x i8] c"Returned from func4\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [17 x i8] c"Dynamic var: %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [21 x i8] c"Returned from func3\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [21 x i8] c"In main, first time\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [45 x i8] c"In main, after __builtin_longjmp from func1\0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func4() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf3)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func3() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func2() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf1)
+ unreachable
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @func1() #0 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: Dynamic var: 10
+; CHECK: Returned from func3
+; CHECK: Dynamic var: 20
+ %dynamic_var = alloca ptr, align 8
+ %0 = alloca i8, i64 4, align 8
+ store ptr %0, ptr %dynamic_var, align 8
+ %1 = load ptr, ptr %dynamic_var, align 8
+ store i32 10, ptr %1, align 4
+ %2 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf2)
+ %cmp = icmp eq i32 %2, 0
+ br i1 %cmp, label %if.then, label %if.else6
+
+if.then: ; preds = %entry
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3)
+ %3 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf3)
+ %cmp1 = icmp eq i32 %3, 0
+ br i1 %cmp1, label %if.then2, label %if.else
+
+if.then2: ; preds = %if.then
+ %call3 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4)
+ call void @func4()
+ br label %if.end
+
+if.else: ; preds = %if.then
+ %call4 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5)
+ %4 = load ptr, ptr %dynamic_var, align 8
+ %5 = load i32, ptr %4, align 4
+ %call5 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.6, i32 noundef signext %5)
+ %6 = load ptr, ptr %dynamic_var, align 8
+ store i32 20, ptr %6, align 4
+ call void @func3()
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then2
+ br label %if.end9
+
+if.else6: ; preds = %entry
+ %call7 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.7)
+ %7 = load ptr, ptr %dynamic_var, align 8
+ %8 = load i32, ptr %7, align 4
+ %call8 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.6, i32 noundef signext %8)
+ call void @func2()
+ br label %if.end9
+
+if.end9: ; preds = %if.else6, %if.end
+ ret i32 0
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %retval = alloca i32, align 4
+ store i32 0, ptr %retval, align 4
+ %0 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.8)
+ %call1 = call signext i32 @func1()
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call2 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.9)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ ret i32 0
+}
+
+attributes #0 = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04-o2.ll
new file mode 100644
index 00000000000000..7a42aced892141
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04-o2.ll
@@ -0,0 +1,157 @@
+; This tests Frame Pointer.
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is with optimization -O2, modified value does not persist.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-04.c'
+source_filename = "builtin-setjmp-longjmp-alloca-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [17 x i8] c"Dynamic var: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: Dynamic var: 10
+; CHECK: Returned from func3
+; CHECK: Dynamic var: 10
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else6
+
+if.then: ; preds = %entry
+ %puts13 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp1 = icmp eq i32 %1, 0
+ br i1 %cmp1, label %if.then2, label %if.else
+
+if.then2: ; preds = %if.then
+ %puts15 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts14 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func3()
+ unreachable
+
+if.else6: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp.i = icmp eq i32 %1, 0
+ br i1 %cmp.i, label %if.then.i, label %if.else6.i
+
+if.then.i: ; preds = %if.then
+ %puts13.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %2 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp1.i = icmp eq i32 %2, 0
+ br i1 %cmp1.i, label %if.then2.i, label %if.else.i
+
+if.then2.i: ; preds = %if.then.i
+ %puts15.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else.i: ; preds = %if.then.i
+ %puts14.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %call5.i = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func3()
+ unreachable
+
+if.else6.i: ; preds = %if.then
+ %puts.i = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %call8.i = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func2()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04.ll
index a75e383212f20b..c0947a4683036d 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-04.ll
@@ -1,15 +1,9 @@
; This tests Frame Pointer.
-; This test case produces Wrong result.
-; FIXME: Correct Output is:
-;First __builtin_setjmp in func1
-;Second __builtin_setjmp in func1
-;Returned from func4
-;Dynamic var: 10
-;Returned from func3
-;Dynamic var: 20
-; TODO: -mbackchain test
-
-; RUN: clang -o %t %s
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is without optimization -O0, modified value persists.
+
+; RUN: clang -O0 -o %t %s
; RUN: %t | FileCheck %s
; ModuleID = 'builtin-setjmp-longjmp-alloca-04.c'
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-00-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-00-o0.ll
new file mode 100644
index 00000000000000..27db27772b2713
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-00-o0.ll
@@ -0,0 +1,286 @@
+; -mbackchain option
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is without optimization -O0, modified value persists.
+; Undefined. Anoop
+
+; RUN: clang -mbackchain -O0 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-00.c'
+source_filename = "builtin-setjmp-longjmp-alloca-00.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [10 x i8] c"In func4\0A\00", align 2
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [10 x i8] c"In func3\0A\00", align 2
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [10 x i8] c"In func2\0A\00", align 2
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.3 = private unnamed_addr constant [33 x i8] c"First __builtin_setjmp in func1\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [34 x i8] c"Second __builtin_setjmp in func1\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [21 x i8] c"Returned from func4\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [21 x i8] c"Returned from func3\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [21 x i8] c"In main, first time\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [45 x i8] c"In main, after __builtin_longjmp from func1\0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func4() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf3)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func3() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func2() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf1)
+ unreachable
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @func1() #0 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 3
+; CHECK: arr: 14
+; CHECK: arr: 39
+; CHECK: arr: 84
+; CHECK: arr: 155
+; CHECK: arr: 258
+; CHECK: arr: 399
+; CHECK: arr: 584
+; CHECK: arr: 819
+
+ %len = alloca i32, align 4
+ %arr = alloca ptr, align 8
+ %i = alloca i32, align 4
+ %i10 = alloca i32, align 4
+ %i21 = alloca i32, align 4
+ %i38 = alloca i32, align 4
+ store i32 10, ptr %len, align 4
+ %0 = load i32, ptr %len, align 4
+ %conv = sext i32 %0 to i64
+ %mul = mul i64 %conv, 4
+ %1 = alloca i8, i64 %mul, align 8
+ store ptr %1, ptr %arr, align 8
+ store i32 0, ptr %i, align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %2 = load i32, ptr %i, align 4
+ %3 = load i32, ptr %len, align 4
+ %cmp = icmp slt i32 %2, %3
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %4 = load i32, ptr %i, align 4
+ %5 = load i32, ptr %i, align 4
+ %mul2 = mul nsw i32 %4, %5
+ %6 = load i32, ptr %i, align 4
+ %add = add nsw i32 %mul2, %6
+ %7 = load ptr, ptr %arr, align 8
+ %8 = load i32, ptr %i, align 4
+ %idxprom = sext i32 %8 to i64
+ %arrayidx = getelementptr inbounds i32, ptr %7, i64 %idxprom
+ store i32 %add, ptr %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %9 = load i32, ptr %i, align 4
+ %inc = add nsw i32 %9, 1
+ store i32 %inc, ptr %i, align 4
+ br label %for.cond, !llvm.loop !5
+
+for.end: ; preds = %for.cond
+ %10 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf2)
+ %cmp3 = icmp eq i32 %10, 0
+ br i1 %cmp3, label %if.then, label %if.else36
+
+if.then: ; preds = %for.end
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3)
+ %11 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf3)
+ %cmp5 = icmp eq i32 %11, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %call8 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4)
+ call void @func4()
+ br label %if.end
+
+if.else: ; preds = %if.then
+ %call9 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5)
+ store i32 0, ptr %i10, align 4
+ br label %for.cond11
+
+for.cond11: ; preds = %for.inc18, %if.else
+ %12 = load i32, ptr %i10, align 4
+ %13 = load i32, ptr %len, align 4
+ %cmp12 = icmp slt i32 %12, %13
+ br i1 %cmp12, label %for.body14, label %for.end20
+
+for.body14: ; preds = %for.cond11
+ %14 = load ptr, ptr %arr, align 8
+ %15 = load i32, ptr %i10, align 4
+ %idxprom15 = sext i32 %15 to i64
+ %arrayidx16 = getelementptr inbounds i32, ptr %14, i64 %idxprom15
+ %16 = load i32, ptr %arrayidx16, align 4
+ %call17 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.6, i32 noundef signext %16)
+ br label %for.inc18
+
+for.inc18: ; preds = %for.body14
+ %17 = load i32, ptr %i10, align 4
+ %inc19 = add nsw i32 %17, 1
+ store i32 %inc19, ptr %i10, align 4
+ br label %for.cond11, !llvm.loop !7
+
+for.end20: ; preds = %for.cond11
+ store i32 0, ptr %i21, align 4
+ br label %for.cond22
+
+for.cond22: ; preds = %for.inc33, %for.end20
+ %18 = load i32, ptr %i21, align 4
+ %19 = load i32, ptr %len, align 4
+ %cmp23 = icmp slt i32 %18, %19
+ br i1 %cmp23, label %for.body25, label %for.end35
+
+for.body25: ; preds = %for.cond22
+ %20 = load i32, ptr %i21, align 4
+ %21 = load i32, ptr %i21, align 4
+ %mul26 = mul nsw i32 %20, %21
+ %22 = load i32, ptr %i21, align 4
+ %mul27 = mul nsw i32 %mul26, %22
+ %23 = load i32, ptr %i21, align 4
+ %24 = load i32, ptr %i21, align 4
+ %mul28 = mul nsw i32 %23, %24
+ %add29 = add nsw i32 %mul27, %mul28
+ %25 = load i32, ptr %i21, align 4
+ %add30 = add nsw i32 %add29, %25
+ %26 = load ptr, ptr %arr, align 8
+ %27 = load i32, ptr %i21, align 4
+ %idxprom31 = sext i32 %27 to i64
+ %arrayidx32 = getelementptr inbounds i32, ptr %26, i64 %idxprom31
+ store i32 %add30, ptr %arrayidx32, align 4
+ br label %for.inc33
+
+for.inc33: ; preds = %for.body25
+ %28 = load i32, ptr %i21, align 4
+ %inc34 = add nsw i32 %28, 1
+ store i32 %inc34, ptr %i21, align 4
+ br label %for.cond22, !llvm.loop !8
+
+for.end35: ; preds = %for.cond22
+ call void @func3()
+ br label %if.end
+
+if.end: ; preds = %for.end35, %if.then7
+ br label %if.end49
+
+if.else36: ; preds = %for.end
+ %call37 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.7)
+ store i32 0, ptr %i38, align 4
+ br label %for.cond39
+
+for.cond39: ; preds = %for.inc46, %if.else36
+ %29 = load i32, ptr %i38, align 4
+ %30 = load i32, ptr %len, align 4
+ %cmp40 = icmp slt i32 %29, %30
+ br i1 %cmp40, label %for.body42, label %for.end48
+
+for.body42: ; preds = %for.cond39
+ %31 = load ptr, ptr %arr, align 8
+ %32 = load i32, ptr %i38, align 4
+ %idxprom43 = sext i32 %32 to i64
+ %arrayidx44 = getelementptr inbounds i32, ptr %31, i64 %idxprom43
+ %33 = load i32, ptr %arrayidx44, align 4
+ %call45 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.6, i32 noundef signext %33)
+ br label %for.inc46
+
+for.inc46: ; preds = %for.body42
+ %34 = load i32, ptr %i38, align 4
+ %inc47 = add nsw i32 %34, 1
+ store i32 %inc47, ptr %i38, align 4
+ br label %for.cond39, !llvm.loop !9
+
+for.end48: ; preds = %for.cond39
+ call void @func2()
+ br label %if.end49
+
+if.end49: ; preds = %for.end48, %if.end
+ ret i32 0
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %retval = alloca i32, align 4
+ store i32 0, ptr %retval, align 4
+ %0 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.8)
+ %call1 = call signext i32 @func1()
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call2 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.9)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ ret i32 0
+}
+
+attributes #0 = { noinline nounwind optnone "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!5 = distinct !{!5, !6}
+!6 = !{!"llvm.loop.mustprogress"}
+!7 = distinct !{!7, !6}
+!8 = distinct !{!8, !6}
+!9 = distinct !{!9, !6}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-00-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-00-o2.ll
new file mode 100644
index 00000000000000..cdc47d53a8405a
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-00-o2.ll
@@ -0,0 +1,170 @@
+; -mbackchain option
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is with optimization -O2, modified value does not persist.
+; Undefined. Anoop
+
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-00.c'
+source_filename = "builtin-setjmp-longjmp-alloca-00.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %0, 0
+ br i1 %cmp3, label %if.then, label %if.else38
+
+if.then: ; preds = %entry
+ %puts77 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp5 = icmp eq i32 %1, 0
+ br i1 %cmp5, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.then
+ %puts82 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts78 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %call18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
+ %call18.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
+ %call18.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
+ %call18.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
+ %call18.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
+ %call18.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
+ %call18.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
+ %call18.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
+ %call18.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
+ %call18.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
+ tail call void @func3()
+ unreachable
+
+if.else38: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %call48 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 0)
+ %call48.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 2)
+ %call48.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 6)
+ %call48.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 12)
+ %call48.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 20)
+ %call48.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 30)
+ %call48.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 42)
+ %call48.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 56)
+ %call48.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 72)
+ %call48.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 90)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-04-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-04-o0.ll
new file mode 100644
index 00000000000000..97ca5d96fecc38
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-04-o0.ll
@@ -0,0 +1,150 @@
+; -mbackchain
+; This tests Frame Pointer.
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is without optimization -O0, modified value persists.
+
+; RUN: clang -mbackchain -O0 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-04.c'
+source_filename = "builtin-setjmp-longjmp-alloca-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [10 x i8] c"In func4\0A\00", align 2
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [10 x i8] c"In func3\0A\00", align 2
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [10 x i8] c"In func2\0A\00", align 2
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.3 = private unnamed_addr constant [33 x i8] c"First __builtin_setjmp in func1\0A\00", align 2
+ at .str.4 = private unnamed_addr constant [34 x i8] c"Second __builtin_setjmp in func1\0A\00", align 2
+ at .str.5 = private unnamed_addr constant [21 x i8] c"Returned from func4\0A\00", align 2
+ at .str.6 = private unnamed_addr constant [17 x i8] c"Dynamic var: %d\0A\00", align 2
+ at .str.7 = private unnamed_addr constant [21 x i8] c"Returned from func3\0A\00", align 2
+ at .str.8 = private unnamed_addr constant [21 x i8] c"In main, first time\0A\00", align 2
+ at .str.9 = private unnamed_addr constant [45 x i8] c"In main, after __builtin_longjmp from func1\0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func4() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf3)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func3() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @func2() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf1)
+ unreachable
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @func1() #0 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: Dynamic var: 10
+; CHECK: Returned from func3
+; CHECK: Dynamic var: 20
+
+ %dynamic_var = alloca ptr, align 8
+ %0 = alloca i8, i64 4, align 8
+ store ptr %0, ptr %dynamic_var, align 8
+ %1 = load ptr, ptr %dynamic_var, align 8
+ store i32 10, ptr %1, align 4
+ %2 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf2)
+ %cmp = icmp eq i32 %2, 0
+ br i1 %cmp, label %if.then, label %if.else6
+
+if.then: ; preds = %entry
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3)
+ %3 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf3)
+ %cmp1 = icmp eq i32 %3, 0
+ br i1 %cmp1, label %if.then2, label %if.else
+
+if.then2: ; preds = %if.then
+ %call3 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4)
+ call void @func4()
+ br label %if.end
+
+if.else: ; preds = %if.then
+ %call4 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5)
+ %4 = load ptr, ptr %dynamic_var, align 8
+ %5 = load i32, ptr %4, align 4
+ %call5 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.6, i32 noundef signext %5)
+ %6 = load ptr, ptr %dynamic_var, align 8
+ store i32 20, ptr %6, align 4
+ call void @func3()
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then2
+ br label %if.end9
+
+if.else6: ; preds = %entry
+ %call7 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.7)
+ %7 = load ptr, ptr %dynamic_var, align 8
+ %8 = load i32, ptr %7, align 4
+ %call8 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.6, i32 noundef signext %8)
+ call void @func2()
+ br label %if.end9
+
+if.end9: ; preds = %if.else6, %if.end
+ ret i32 0
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %retval = alloca i32, align 4
+ store i32 0, ptr %retval, align 4
+ %0 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.8)
+ %call1 = call signext i32 @func1()
+ br label %if.end
+
+if.else: ; preds = %entry
+ %call2 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.9)
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ ret i32 0
+}
+
+attributes #0 = { noinline nounwind optnone "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-04-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-04-o2.ll
new file mode 100644
index 00000000000000..25204c40fe0fa0
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-alloca-backchain-04-o2.ll
@@ -0,0 +1,133 @@
+; -mbackchain option
+; This tests Frame Pointer.
+; This tests program output for Frame Pointer.
+; Non-volatile local variable being modified between setjmp and longjmp call.
+; This test is with optimization -O2, modified value does not persist.
+
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ModuleID = 'builtin-setjmp-longjmp-alloca-04.c'
+source_filename = "builtin-setjmp-longjmp-alloca-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [17 x i8] c"Dynamic var: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+; CHECK: First __builtin_setjmp in func1
+; CHECK: Second __builtin_setjmp in func1
+; CHECK: Returned from func4
+; CHECK: Dynamic var: 10
+; CHECK: Returned from func3
+; CHECK: Dynamic var: 10
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else6
+
+if.then: ; preds = %entry
+ %puts13 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp1 = icmp eq i32 %1, 0
+ br i1 %cmp1, label %if.then2, label %if.else
+
+if.then2: ; preds = %if.then
+ %puts15 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts14 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func3()
+ unreachable
+
+if.else6: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %call8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext 10)
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #5 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-03.ll
index d2a3c85576137e..85916848d85858 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-03.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-03.ll
@@ -1,24 +1,33 @@
-;Test -mbackchain longjmp load from jmp_buf.
-; Frame pointer from Slot 1.
-; Jump address from Slot 2.
-; Backchain Value from Slot 3.
-; Stack Pointer from Slot 4.
-; Literal Pool Pointer from Slot 5.
+; -mbackchain option
+; This test is intended to test control flow of setjmp/longjmp calls,
+; reachable and unreachabel paths both.
-; RUN: llc < %s | FileCheck %s
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
-; ModuleID = 'builtin-setjmp-longjmp-backchain-02.c'
-source_filename = "builtin-setjmp-longjmp-backchain-02.c"
+; ********** Output should be as follows: ***********
+; CHECK: setjmp has been called
+; CHECK: Calling function foo
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-03.c'
+source_filename = "builtin-setjmp-longjmp-03.c"
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
target triple = "s390x-unknown-linux-gnu"
@buf = dso_local global [20 x ptr] zeroinitializer, align 8
- at str = private unnamed_addr constant [9 x i8] c"call foo\00", align 1
- at str.2 = private unnamed_addr constant [7 x i8] c"return\00", align 1
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+ at str.7 = private unnamed_addr constant [23 x i8] c"setjmp has been called\00", align 1
+ at str.8 = private unnamed_addr constant [21 x i8] c"Calling function foo\00", align 1
+ at str.10 = private unnamed_addr constant [24 x i8] c"longjmp has been called\00", align 1
-; Function Attrs: noreturn nounwind
+; Function Attrs: noinline noreturn nounwind
define dso_local void @foo() local_unnamed_addr #0 {
entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
unreachable
}
@@ -26,44 +35,49 @@ entry:
; Function Attrs: noreturn nounwind
declare void @llvm.eh.sjlj.longjmp(ptr) #1
-; Function Attrs: nounwind
-define dso_local noundef signext range(i32 0, 2) i32 @main(i32 noundef signext %argc, ptr nocapture noundef readnone %argv) local_unnamed_addr #2 {
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #2 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #3 {
entry:
%0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
- %tobool.not = icmp eq i32 %0, 0
- br i1 %tobool.not, label %if.end, label %if.then
+ %cmp.not = icmp eq i32 %0, 0
+ br i1 %cmp.not, label %if.end, label %if.then
if.then: ; preds = %entry
- %puts2 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.2)
- ret i32 0
+ %puts6 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 0) #1
+ unreachable
if.end: ; preds = %entry
-; CHECK: stmg %r11, %r15, 88(%r15)
-; CHECK: larl %r1, buf
-; CHECK: lg %r2, 8(%r1)
-; CHECK: lg %r11, 0(%r1)
-; CHECK: lg %r13, 32(%r1)
-; CHECK: lg %r3, 16(%r1)
-; CHECK: stg %r3, 0(%r15)
-; CHECK: lg %r15, 24(%r1)
-; CHECK: br %r2
-
- %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
- tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.7)
+ %puts4 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.8)
+ tail call void @foo()
unreachable
}
; Function Attrs: nounwind
-declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #5
; Function Attrs: nofree nounwind
-declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #4
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #6
-attributes #0 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
attributes #1 = { noreturn nounwind }
-attributes #2 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
-attributes #3 = { nounwind }
-attributes #4 = { nofree nounwind }
+attributes #2 = { nofree noinline nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nofree noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nofree nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
@@ -71,4 +85,4 @@ attributes #4 = { nofree nounwind }
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
-!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 79880371396d6e486bf6bacd6c4087ebdac591f8)"}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-04-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-04-o0.ll
new file mode 100644
index 00000000000000..5ba216d137132a
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-04-o0.ll
@@ -0,0 +1,95 @@
+; -mbackchain option
+; Tests output of local valiable being modified between setjmp and longjmp call.
+; This test is without optimizations -O0.
+
+; RUN: clang -mbackchain -O0 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ********** Output should be as follows: ***********
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-04.c'
+source_filename = "builtin-setjmp-longjmp-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [42 x i8] c"Calling longjmp from inside function foo\0A\00", align 2
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [29 x i8] c"Performing function recover\0A\00", align 2
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at .str.5 = private unnamed_addr constant [50 x i8] c"This point should never be reached local_var=%d \0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @foo() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @recover() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ ret void
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %local_var = alloca i32, align 4
+ store i32 10, ptr %local_var, align 4
+ %0 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf)
+ %cmp = icmp ne i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %1 = load i32, ptr %local_var, align 4
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef signext %1)
+ call void @recover()
+ call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %2 = load i32, ptr %local_var, align 4
+ %call1 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3, i32 noundef signext %2)
+ store i32 20, ptr %local_var, align 4
+ %3 = load i32, ptr %local_var, align 4
+ %call2 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4, i32 noundef signext %3)
+ call void @foo()
+ %4 = load i32, ptr %local_var, align 4
+ %call3 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5, i32 noundef signext %4)
+ ret i32 0
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #3
+
+; Function Attrs: noreturn nounwind
+declare void @exit(i32 noundef signext) #4
+
+attributes #0 = { noinline nounwind optnone "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind }
+attributes #4 = { noreturn nounwind "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-04-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-04-o2.ll
new file mode 100644
index 00000000000000..1abd9eadcf489a
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-backchain-04-o2.ll
@@ -0,0 +1,95 @@
+; -mbackchain
+; Tests output of local valiable being modified between setjmp and longjmp call.
+; This test output is at -O2 and it does not match the output at -O0.
+; Any modification to non-volatile local variable between setjmp
+; and longjmp calls will not persist.
+
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; ********** Output does not match with -O0 Undefined: ***********
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=10
+; CHECK: Performing function recover
+
+
+; ModuleID = 'builtin-setjmp-longjmp-04.c'
+source_filename = "builtin-setjmp-longjmp-04.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ br i1 %cmp.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext 10)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext 10)
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext 20)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #6
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #7
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { nounwind }
+attributes #6 = { nofree noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nofree nounwind }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-02-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-02-o2.ll
new file mode 100644
index 00000000000000..0f7ae265356352
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-02-o2.ll
@@ -0,0 +1,133 @@
+; global malloc'd variable being modified between setjmp and longjmp call.
+; modified value persists.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called global_var=10
+; CHECK: Calling function foo global_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+; CHECK: setjmp has been called global_var=30
+; CHECK: Calling function foo global_var=40
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=40
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-global-02.c'
+source_filename = "builtin-setjmp-longjmp-malloc-global-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at global_var = dso_local local_unnamed_addr global ptr null, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [39 x i8] c"setjmp has been called global_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [37 x i8] c"Calling function foo global_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(4) ptr @malloc(i64 noundef 4) #10
+ store ptr %call, ptr @global_var, align 8, !tbaa !4
+ store i32 10, ptr %call, align 4, !tbaa !8
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ %.pre = load ptr, ptr @global_var, align 8, !tbaa !4
+ %.pre11 = load i32, ptr %.pre, align 4, !tbaa !8
+ br i1 %cmp.not, label %if.end4, label %if.then
+
+if.then: ; preds = %entry
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %.pre11)
+ tail call void @recover()
+ %1 = load ptr, ptr @global_var, align 8, !tbaa !4
+ %2 = load i32, ptr %1, align 4, !tbaa !8
+ %cmp2.not = icmp eq i32 %2, 20
+ br i1 %cmp2.not, label %if.end, label %if.then3
+
+if.then3: ; preds = %if.then
+ tail call void @free(ptr noundef nonnull %1) #6
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %if.then
+ store i32 30, ptr %1, align 4, !tbaa !8
+ br label %if.end4
+
+if.end4: ; preds = %entry, %if.end
+ %3 = phi i32 [ 30, %if.end ], [ %.pre11, %entry ]
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %3)
+ %4 = load ptr, ptr @global_var, align 8, !tbaa !4
+ %5 = load i32, ptr %4, align 4, !tbaa !8
+ %cmp6 = icmp eq i32 %5, 10
+ %. = select i1 %cmp6, i32 20, i32 40
+ store i32 %., ptr %4, align 4, !tbaa !8
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %.)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #5
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #6
+
+; Function Attrs: mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite)
+declare void @free(ptr allocptr nocapture noundef) local_unnamed_addr #7
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #8
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #9
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind }
+attributes #7 = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #9 = { nofree nounwind }
+attributes #10 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"any pointer", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = !{!9, !9, i64 0}
+!9 = !{!"int", !6, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-0l-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-0l-o2.ll
new file mode 100644
index 00000000000000..2bd230b0980111
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-0l-o2.ll
@@ -0,0 +1,109 @@
+; global malloc'd variable being modified between setjmp and longjmp call.
+; modified value persists.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called global_var=10
+; CHECK: Calling function foo global_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-global-0l.c'
+source_filename = "builtin-setjmp-longjmp-malloc-global-0l.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at global_var = dso_local local_unnamed_addr global ptr null, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [39 x i8] c"setjmp has been called global_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [37 x i8] c"Calling function foo global_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(4) ptr @malloc(i64 noundef 4) #9
+ store ptr %call, ptr @global_var, align 8, !tbaa !4
+ store i32 10, ptr %call, align 4, !tbaa !8
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ %1 = load ptr, ptr @global_var, align 8, !tbaa !4
+ %2 = load i32, ptr %1, align 4, !tbaa !8
+ br i1 %cmp.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %2)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %2)
+ %3 = load ptr, ptr @global_var, align 8, !tbaa !4
+ store i32 20, ptr %3, align 4, !tbaa !8
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext 20)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #5
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #6
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #7
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #8
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind }
+attributes #7 = { nofree noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree nounwind }
+attributes #9 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"any pointer", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = !{!9, !9, i64 0}
+!9 = !{!"int", !6, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-backchain-02-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-backchain-02-o2.ll
new file mode 100644
index 00000000000000..4604af5e9e35e6
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-backchain-02-o2.ll
@@ -0,0 +1,135 @@
+; -mbackchain
+; global malloc'd variable being modified between setjmp and longjmp call.
+; modified value persists.
+
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called global_var=10
+; CHECK: Calling function foo global_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+; CHECK: setjmp has been called global_var=30
+; CHECK: Calling function foo global_var=40
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=40
+; CHECK: Performing function recover
+
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-global-02.c'
+source_filename = "builtin-setjmp-longjmp-malloc-global-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at global_var = dso_local local_unnamed_addr global ptr null, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [39 x i8] c"setjmp has been called global_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [37 x i8] c"Calling function foo global_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(4) ptr @malloc(i64 noundef 4) #10
+ store ptr %call, ptr @global_var, align 8, !tbaa !4
+ store i32 10, ptr %call, align 4, !tbaa !8
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ %.pre = load ptr, ptr @global_var, align 8, !tbaa !4
+ %.pre11 = load i32, ptr %.pre, align 4, !tbaa !8
+ br i1 %cmp.not, label %if.end4, label %if.then
+
+if.then: ; preds = %entry
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %.pre11)
+ tail call void @recover()
+ %1 = load ptr, ptr @global_var, align 8, !tbaa !4
+ %2 = load i32, ptr %1, align 4, !tbaa !8
+ %cmp2.not = icmp eq i32 %2, 20
+ br i1 %cmp2.not, label %if.end, label %if.then3
+
+if.then3: ; preds = %if.then
+ tail call void @free(ptr noundef nonnull %1) #6
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %if.then
+ store i32 30, ptr %1, align 4, !tbaa !8
+ br label %if.end4
+
+if.end4: ; preds = %entry, %if.end
+ %3 = phi i32 [ 30, %if.end ], [ %.pre11, %entry ]
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %3)
+ %4 = load ptr, ptr @global_var, align 8, !tbaa !4
+ %5 = load i32, ptr %4, align 4, !tbaa !8
+ %cmp6 = icmp eq i32 %5, 10
+ %. = select i1 %cmp6, i32 20, i32 40
+ store i32 %., ptr %4, align 4, !tbaa !8
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %.)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #5
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #6
+
+; Function Attrs: mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite)
+declare void @free(ptr allocptr nocapture noundef) local_unnamed_addr #7
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #8
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #9
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind }
+attributes #7 = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #9 = { nofree nounwind }
+attributes #10 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"any pointer", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = !{!9, !9, i64 0}
+!9 = !{!"int", !6, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-backchain-0l-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-backchain-0l-o2.ll
new file mode 100644
index 00000000000000..515863cd8d8278
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-global-backchain-0l-o2.ll
@@ -0,0 +1,111 @@
+; -mbackchain
+; global malloc'd variable being modified between setjmp and longjmp call.
+; modified value persists.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called global_var=10
+; CHECK: Calling function foo global_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-global-0l.c'
+source_filename = "builtin-setjmp-longjmp-malloc-global-0l.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at global_var = dso_local local_unnamed_addr global ptr null, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [39 x i8] c"setjmp has been called global_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [37 x i8] c"Calling function foo global_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(4) ptr @malloc(i64 noundef 4) #9
+ store ptr %call, ptr @global_var, align 8, !tbaa !4
+ store i32 10, ptr %call, align 4, !tbaa !8
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ %1 = load ptr, ptr @global_var, align 8, !tbaa !4
+ %2 = load i32, ptr %1, align 4, !tbaa !8
+ br i1 %cmp.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %2)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %2)
+ %3 = load ptr, ptr @global_var, align 8, !tbaa !4
+ store i32 20, ptr %3, align 4, !tbaa !8
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext 20)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #5
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #6
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #7
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #8
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind }
+attributes #7 = { nofree noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree nounwind }
+attributes #9 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"any pointer", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = !{!9, !9, i64 0}
+!9 = !{!"int", !6, i64 0}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-01-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-01-o0.ll
new file mode 100644
index 00000000000000..d34774a4f7679a
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-01-o0.ll
@@ -0,0 +1,105 @@
+; Non-volatile local malloc'd variable being modified between setjmp and longjmp call.
+; This test is without optimization -O0, modified value persists.
+
+; RUN: clang -O0 -o %t %s
+; RUN: %t | FileCheck %s
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-local-01.c'
+source_filename = "builtin-setjmp-longjmp-malloc-local-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [42 x i8] c"Calling longjmp from inside function foo\0A\00", align 2
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [29 x i8] c"Performing function recover\0A\00", align 2
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at .str.5 = private unnamed_addr constant [50 x i8] c"This point should never be reached local_var=%d \0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @foo() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @recover() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ ret void
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %local_var = alloca ptr, align 8
+ %call = call noalias ptr @malloc(i64 noundef 4) #6
+ store ptr %call, ptr %local_var, align 8
+ %0 = load ptr, ptr %local_var, align 8
+ store i32 10, ptr %0, align 4
+ %1 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf)
+ %cmp = icmp ne i32 %1, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %2 = load ptr, ptr %local_var, align 8
+ %3 = load i32, ptr %2, align 4
+ %call1 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef signext %3)
+ call void @recover()
+ call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %4 = load ptr, ptr %local_var, align 8
+ %5 = load i32, ptr %4, align 4
+ %call2 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3, i32 noundef signext %5)
+ %6 = load ptr, ptr %local_var, align 8
+ store i32 20, ptr %6, align 4
+ %7 = load ptr, ptr %local_var, align 8
+ %8 = load i32, ptr %7, align 4
+ %call3 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4, i32 noundef signext %8)
+ call void @foo()
+ %9 = load ptr, ptr %local_var, align 8
+ %10 = load i32, ptr %9, align 4
+ %call4 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5, i32 noundef signext %10)
+ ret i32 0
+}
+
+; Function Attrs: nounwind allocsize(0)
+declare noalias ptr @malloc(i64 noundef) #3
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: noreturn nounwind
+declare void @exit(i32 noundef signext) #5
+
+attributes #0 = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind allocsize(0) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-02-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-02-o0.ll
new file mode 100644
index 00000000000000..13965d3a351441
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-02-o0.ll
@@ -0,0 +1,147 @@
+; Non-volatile local malloc'd variable being modified between setjmp and longjmp call.
+; This test is without optimization -O0, modified value persists.
+; FIXME: Add this test case when local malloc'd non-volatile variable is fixed.
+; It will create infinite loop.
+
+; RUN: clang -O0 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+; CHECK: setjmp has been called local_var=30
+; CHECK: Calling function foo local_var=40
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=40
+; CHECK: Performing function recover
+
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-local-02.c'
+source_filename = "builtin-setjmp-longjmp-malloc-local-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [42 x i8] c"Calling longjmp from inside function foo\0A\00", align 2
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [29 x i8] c"Performing function recover\0A\00", align 2
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at .str.5 = private unnamed_addr constant [50 x i8] c"This point should never be reached local_var=%d \0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @foo() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @recover() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ ret void
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %retval = alloca i32, align 4
+ %local_var = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ %call = call noalias ptr @malloc(i64 noundef 4) #7
+ store ptr %call, ptr %local_var, align 8
+ %0 = load ptr, ptr %local_var, align 8
+ store i32 10, ptr %0, align 4
+ %1 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf)
+ %cmp = icmp ne i32 %1, 0
+ br i1 %cmp, label %if.then, label %if.end4
+
+if.then: ; preds = %entry
+ %2 = load ptr, ptr %local_var, align 8
+ %3 = load i32, ptr %2, align 4
+ %call1 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef signext %3)
+ call void @recover()
+ %4 = load ptr, ptr %local_var, align 8
+ %5 = load i32, ptr %4, align 4
+ %cmp2 = icmp ne i32 %5, 20
+ br i1 %cmp2, label %if.then3, label %if.end
+
+if.then3: ; preds = %if.then
+ %6 = load ptr, ptr %local_var, align 8
+ call void @free(ptr noundef %6) #4
+ call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %if.then
+ %7 = load ptr, ptr %local_var, align 8
+ store i32 30, ptr %7, align 4
+ br label %if.end4
+
+if.end4: ; preds = %if.end, %entry
+ %8 = load ptr, ptr %local_var, align 8
+ %9 = load i32, ptr %8, align 4
+ %call5 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3, i32 noundef signext %9)
+ %10 = load ptr, ptr %local_var, align 8
+ %11 = load i32, ptr %10, align 4
+ %cmp6 = icmp eq i32 %11, 10
+ br i1 %cmp6, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.end4
+ %12 = load ptr, ptr %local_var, align 8
+ store i32 20, ptr %12, align 4
+ br label %if.end8
+
+if.else: ; preds = %if.end4
+ %13 = load ptr, ptr %local_var, align 8
+ store i32 40, ptr %13, align 4
+ br label %if.end8
+
+if.end8: ; preds = %if.else, %if.then7
+ %14 = load ptr, ptr %local_var, align 8
+ %15 = load i32, ptr %14, align 4
+ %call9 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4, i32 noundef signext %15)
+ call void @foo()
+ %16 = load ptr, ptr %local_var, align 8
+ %17 = load i32, ptr %16, align 4
+ %call10 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5, i32 noundef signext %17)
+ ret i32 0
+}
+
+; Function Attrs: nounwind allocsize(0)
+declare noalias ptr @malloc(i64 noundef) #3
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+declare void @free(ptr noundef) #5
+
+; Function Attrs: noreturn nounwind
+declare void @exit(i32 noundef signext) #6
+
+attributes #0 = { noinline nounwind optnone "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind allocsize(0) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-03.ll
new file mode 100644
index 00000000000000..d72eb409fdad88
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-03.ll
@@ -0,0 +1,393 @@
+; Non-volatile local malloc'd variable being modified between setjmp and longjmp call.
+; size of malloc is 25 and array variable is not kept on stack.
+; This test is with optimization -O2, modified value persists.
+; For size of malloc 20, all array values are stored to stack, and modified
+; values does not persist.
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+; CHECK: arr: 110
+; CHECK: arr: 132
+; CHECK: arr: 156
+; CHECK: arr: 182
+; CHECK: arr: 210
+; CHECK: arr: 240
+; CHECK: arr: 272
+; CHECK: arr: 306
+; CHECK: arr: 342
+; CHECK: arr: 380
+; CHECK: arr: 420
+; CHECK: arr: 462
+; CHECK: arr: 506
+; CHECK: arr: 552
+; CHECK: arr: 600
+; CHECK: In func3
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 3
+; CHECK: arr: 14
+; CHECK: arr: 39
+; CHECK: arr: 84
+; CHECK: arr: 155
+; CHECK: arr: 258
+; CHECK: arr: 399
+; CHECK: arr: 584
+; CHECK: arr: 819
+; CHECK: arr: 1110
+; CHECK: arr: 1463
+; CHECK: arr: 1884
+; CHECK: arr: 2379
+; CHECK: arr: 2954
+; CHECK: arr: 3615
+; CHECK: arr: 4368
+; CHECK: arr: 5219
+; CHECK: arr: 6174
+; CHECK: arr: 7239
+; CHECK: arr: 8420
+; CHECK: arr: 9723
+; CHECK: arr: 11154
+; CHECK: arr: 12719
+; CHECK: arr: 14424
+
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-local-03.c'
+source_filename = "builtin-setjmp-longjmp-malloc-local-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(100) ptr @malloc(i64 noundef 100) #9
+ store i32 0, ptr %call, align 4, !tbaa !4
+ %arrayidx.1 = getelementptr inbounds i8, ptr %call, i64 4
+ store i32 2, ptr %arrayidx.1, align 4, !tbaa !4
+ %arrayidx.2 = getelementptr inbounds i8, ptr %call, i64 8
+ store i32 6, ptr %arrayidx.2, align 4, !tbaa !4
+ %arrayidx.3 = getelementptr inbounds i8, ptr %call, i64 12
+ store i32 12, ptr %arrayidx.3, align 4, !tbaa !4
+ %arrayidx.4 = getelementptr inbounds i8, ptr %call, i64 16
+ store i32 20, ptr %arrayidx.4, align 4, !tbaa !4
+ %arrayidx.5 = getelementptr inbounds i8, ptr %call, i64 20
+ store i32 30, ptr %arrayidx.5, align 4, !tbaa !4
+ %arrayidx.6 = getelementptr inbounds i8, ptr %call, i64 24
+ store i32 42, ptr %arrayidx.6, align 4, !tbaa !4
+ %arrayidx.7 = getelementptr inbounds i8, ptr %call, i64 28
+ store i32 56, ptr %arrayidx.7, align 4, !tbaa !4
+ %arrayidx.8 = getelementptr inbounds i8, ptr %call, i64 32
+ store i32 72, ptr %arrayidx.8, align 4, !tbaa !4
+ %arrayidx.9 = getelementptr inbounds i8, ptr %call, i64 36
+ store i32 90, ptr %arrayidx.9, align 4, !tbaa !4
+ %arrayidx.10 = getelementptr inbounds i8, ptr %call, i64 40
+ store i32 110, ptr %arrayidx.10, align 4, !tbaa !4
+ %arrayidx.11 = getelementptr inbounds i8, ptr %call, i64 44
+ store i32 132, ptr %arrayidx.11, align 4, !tbaa !4
+ %arrayidx.12 = getelementptr inbounds i8, ptr %call, i64 48
+ store i32 156, ptr %arrayidx.12, align 4, !tbaa !4
+ %arrayidx.13 = getelementptr inbounds i8, ptr %call, i64 52
+ store i32 182, ptr %arrayidx.13, align 4, !tbaa !4
+ %arrayidx.14 = getelementptr inbounds i8, ptr %call, i64 56
+ store i32 210, ptr %arrayidx.14, align 4, !tbaa !4
+ %arrayidx.15 = getelementptr inbounds i8, ptr %call, i64 60
+ store i32 240, ptr %arrayidx.15, align 4, !tbaa !4
+ %arrayidx.16 = getelementptr inbounds i8, ptr %call, i64 64
+ store i32 272, ptr %arrayidx.16, align 4, !tbaa !4
+ %arrayidx.17 = getelementptr inbounds i8, ptr %call, i64 68
+ store i32 306, ptr %arrayidx.17, align 4, !tbaa !4
+ %arrayidx.18 = getelementptr inbounds i8, ptr %call, i64 72
+ store i32 342, ptr %arrayidx.18, align 4, !tbaa !4
+ %arrayidx.19 = getelementptr inbounds i8, ptr %call, i64 76
+ store i32 380, ptr %arrayidx.19, align 4, !tbaa !4
+ %arrayidx.20 = getelementptr inbounds i8, ptr %call, i64 80
+ store i32 420, ptr %arrayidx.20, align 4, !tbaa !4
+ %arrayidx.21 = getelementptr inbounds i8, ptr %call, i64 84
+ store i32 462, ptr %arrayidx.21, align 4, !tbaa !4
+ %arrayidx.22 = getelementptr inbounds i8, ptr %call, i64 88
+ store i32 506, ptr %arrayidx.22, align 4, !tbaa !4
+ %arrayidx.23 = getelementptr inbounds i8, ptr %call, i64 92
+ store i32 552, ptr %arrayidx.23, align 4, !tbaa !4
+ %arrayidx.24 = getelementptr inbounds i8, ptr %call, i64 96
+ store i32 600, ptr %arrayidx.24, align 4, !tbaa !4
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %0, 0
+ br i1 %cmp3, label %if.then, label %if.else39
+
+if.then: ; preds = %entry
+ %puts79 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp6 = icmp eq i32 %1, 0
+ br i1 %cmp6, label %if.then8, label %if.else
+
+if.then8: ; preds = %if.then
+ %puts84 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts80 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %2 = load i32, ptr %call, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %2)
+ %3 = load i32, ptr %arrayidx.1, align 4, !tbaa !4
+ %call19.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %3)
+ %4 = load i32, ptr %arrayidx.2, align 4, !tbaa !4
+ %call19.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %4)
+ %5 = load i32, ptr %arrayidx.3, align 4, !tbaa !4
+ %call19.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %5)
+ %6 = load i32, ptr %arrayidx.4, align 4, !tbaa !4
+ %call19.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %6)
+ %7 = load i32, ptr %arrayidx.5, align 4, !tbaa !4
+ %call19.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %7)
+ %8 = load i32, ptr %arrayidx.6, align 4, !tbaa !4
+ %call19.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %8)
+ %9 = load i32, ptr %arrayidx.7, align 4, !tbaa !4
+ %call19.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %9)
+ %10 = load i32, ptr %arrayidx.8, align 4, !tbaa !4
+ %call19.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %10)
+ %11 = load i32, ptr %arrayidx.9, align 4, !tbaa !4
+ %call19.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %11)
+ %12 = load i32, ptr %arrayidx.10, align 4, !tbaa !4
+ %call19.10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %12)
+ %13 = load i32, ptr %arrayidx.11, align 4, !tbaa !4
+ %call19.11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %13)
+ %14 = load i32, ptr %arrayidx.12, align 4, !tbaa !4
+ %call19.12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %14)
+ %15 = load i32, ptr %arrayidx.13, align 4, !tbaa !4
+ %call19.13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %15)
+ %16 = load i32, ptr %arrayidx.14, align 4, !tbaa !4
+ %call19.14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %16)
+ %17 = load i32, ptr %arrayidx.15, align 4, !tbaa !4
+ %call19.15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %17)
+ %18 = load i32, ptr %arrayidx.16, align 4, !tbaa !4
+ %call19.16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %18)
+ %19 = load i32, ptr %arrayidx.17, align 4, !tbaa !4
+ %call19.17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %19)
+ %20 = load i32, ptr %arrayidx.18, align 4, !tbaa !4
+ %call19.18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %20)
+ %21 = load i32, ptr %arrayidx.19, align 4, !tbaa !4
+ %call19.19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %21)
+ %22 = load i32, ptr %arrayidx.20, align 4, !tbaa !4
+ %call19.20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %22)
+ %23 = load i32, ptr %arrayidx.21, align 4, !tbaa !4
+ %call19.21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %23)
+ %24 = load i32, ptr %arrayidx.22, align 4, !tbaa !4
+ %call19.22 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %24)
+ %25 = load i32, ptr %arrayidx.23, align 4, !tbaa !4
+ %call19.23 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %25)
+ %26 = load i32, ptr %arrayidx.24, align 4, !tbaa !4
+ %call19.24 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %26)
+ br label %for.body28
+
+for.cond.cleanup27: ; preds = %for.body28
+ tail call void @func3()
+ unreachable
+
+for.body28: ; preds = %for.body28, %if.else
+ %indvars.iv = phi i64 [ 0, %if.else ], [ %indvars.iv.next.4, %for.body28 ]
+ %indvars96 = trunc i64 %indvars.iv to i32
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %indvars = trunc i64 %indvars.iv.next to i32
+ %mul3081 = mul nuw nsw i32 %indvars, %indvars96
+ %add3283 = add nuw nsw i32 %mul3081, 1
+ %add33 = mul nuw nsw i32 %add3283, %indvars96
+ %arrayidx35 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv
+ store i32 %add33, ptr %arrayidx35, align 4, !tbaa !4
+ %indvars96.1 = trunc i64 %indvars.iv.next to i32
+ %indvars.iv.next.1 = add nuw nsw i64 %indvars.iv, 2
+ %indvars.1 = trunc i64 %indvars.iv.next.1 to i32
+ %mul3081.1 = mul nuw nsw i32 %indvars.1, %indvars96.1
+ %add3283.1 = add nuw nsw i32 %mul3081.1, 1
+ %add33.1 = mul nuw nsw i32 %add3283.1, %indvars96.1
+ %arrayidx35.1 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv.next
+ store i32 %add33.1, ptr %arrayidx35.1, align 4, !tbaa !4
+ %indvars96.2 = trunc i64 %indvars.iv.next.1 to i32
+ %indvars.iv.next.2 = add nuw nsw i64 %indvars.iv, 3
+ %indvars.2 = trunc i64 %indvars.iv.next.2 to i32
+ %mul3081.2 = mul nuw nsw i32 %indvars.2, %indvars96.2
+ %add3283.2 = add nuw nsw i32 %mul3081.2, 1
+ %add33.2 = mul nuw nsw i32 %add3283.2, %indvars96.2
+ %arrayidx35.2 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv.next.1
+ store i32 %add33.2, ptr %arrayidx35.2, align 4, !tbaa !4
+ %indvars96.3 = trunc i64 %indvars.iv.next.2 to i32
+ %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
+ %indvars.3 = trunc i64 %indvars.iv.next.3 to i32
+ %mul3081.3 = mul nuw nsw i32 %indvars.3, %indvars96.3
+ %add3283.3 = add nuw nsw i32 %mul3081.3, 1
+ %add33.3 = mul nuw nsw i32 %add3283.3, %indvars96.3
+ %arrayidx35.3 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv.next.2
+ store i32 %add33.3, ptr %arrayidx35.3, align 4, !tbaa !4
+ %indvars96.4 = trunc i64 %indvars.iv.next.3 to i32
+ %indvars.iv.next.4 = add nuw nsw i64 %indvars.iv, 5
+ %indvars.4 = trunc i64 %indvars.iv.next.4 to i32
+ %mul3081.4 = mul nuw nsw i32 %indvars.4, %indvars96.4
+ %add3283.4 = add nuw nsw i32 %mul3081.4, 1
+ %add33.4 = mul nuw nsw i32 %add3283.4, %indvars96.4
+ %arrayidx35.4 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv.next.3
+ store i32 %add33.4, ptr %arrayidx35.4, align 4, !tbaa !4
+ %exitcond.not.4 = icmp eq i64 %indvars.iv.next.4, 25
+ br i1 %exitcond.not.4, label %for.cond.cleanup27, label %for.body28, !llvm.loop !8
+
+if.else39: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %27 = load i32, ptr %call, align 4, !tbaa !4
+ %call49 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %27)
+ %28 = load i32, ptr %arrayidx.1, align 4, !tbaa !4
+ %call49.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %28)
+ %29 = load i32, ptr %arrayidx.2, align 4, !tbaa !4
+ %call49.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %29)
+ %30 = load i32, ptr %arrayidx.3, align 4, !tbaa !4
+ %call49.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %30)
+ %31 = load i32, ptr %arrayidx.4, align 4, !tbaa !4
+ %call49.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %31)
+ %32 = load i32, ptr %arrayidx.5, align 4, !tbaa !4
+ %call49.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %32)
+ %33 = load i32, ptr %arrayidx.6, align 4, !tbaa !4
+ %call49.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %33)
+ %34 = load i32, ptr %arrayidx.7, align 4, !tbaa !4
+ %call49.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %34)
+ %35 = load i32, ptr %arrayidx.8, align 4, !tbaa !4
+ %call49.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %35)
+ %36 = load i32, ptr %arrayidx.9, align 4, !tbaa !4
+ %call49.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %36)
+ %37 = load i32, ptr %arrayidx.10, align 4, !tbaa !4
+ %call49.10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %37)
+ %38 = load i32, ptr %arrayidx.11, align 4, !tbaa !4
+ %call49.11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %38)
+ %39 = load i32, ptr %arrayidx.12, align 4, !tbaa !4
+ %call49.12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %39)
+ %40 = load i32, ptr %arrayidx.13, align 4, !tbaa !4
+ %call49.13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %40)
+ %41 = load i32, ptr %arrayidx.14, align 4, !tbaa !4
+ %call49.14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %41)
+ %42 = load i32, ptr %arrayidx.15, align 4, !tbaa !4
+ %call49.15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %42)
+ %43 = load i32, ptr %arrayidx.16, align 4, !tbaa !4
+ %call49.16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %43)
+ %44 = load i32, ptr %arrayidx.17, align 4, !tbaa !4
+ %call49.17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %44)
+ %45 = load i32, ptr %arrayidx.18, align 4, !tbaa !4
+ %call49.18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %45)
+ %46 = load i32, ptr %arrayidx.19, align 4, !tbaa !4
+ %call49.19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %46)
+ %47 = load i32, ptr %arrayidx.20, align 4, !tbaa !4
+ %call49.20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %47)
+ %48 = load i32, ptr %arrayidx.21, align 4, !tbaa !4
+ %call49.21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %48)
+ %49 = load i32, ptr %arrayidx.22, align 4, !tbaa !4
+ %call49.22 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %49)
+ %50 = load i32, ptr %arrayidx.23, align 4, !tbaa !4
+ %call49.23 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %50)
+ %51 = load i32, ptr %arrayidx.24, align 4, !tbaa !4
+ %call49.24 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %51)
+ tail call void @free(ptr noundef nonnull %call) #5
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #4
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite)
+declare void @free(ptr allocptr nocapture noundef) local_unnamed_addr #6
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #7 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #8
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { nounwind }
+attributes #6 = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree nounwind }
+attributes #9 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = distinct !{!8, !9}
+!9 = !{!"llvm.loop.mustprogress"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-01-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-01-o0.ll
new file mode 100644
index 00000000000000..26c86d6d5ca983
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-01-o0.ll
@@ -0,0 +1,106 @@
+; -mbackchain
+; Non-volatile local malloc'd variable being modified between setjmp and longjmp call.
+; This test is without optimization -O0, modified value persists.
+
+; RUN: clang -mbackchain -O0 -o %t %s
+; RUN: %t | FileCheck %s
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-local-01.c'
+source_filename = "builtin-setjmp-longjmp-malloc-local-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [42 x i8] c"Calling longjmp from inside function foo\0A\00", align 2
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [29 x i8] c"Performing function recover\0A\00", align 2
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at .str.5 = private unnamed_addr constant [50 x i8] c"This point should never be reached local_var=%d \0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @foo() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @recover() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ ret void
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %local_var = alloca ptr, align 8
+ %call = call noalias ptr @malloc(i64 noundef 4) #6
+ store ptr %call, ptr %local_var, align 8
+ %0 = load ptr, ptr %local_var, align 8
+ store i32 10, ptr %0, align 4
+ %1 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf)
+ %cmp = icmp ne i32 %1, 0
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %2 = load ptr, ptr %local_var, align 8
+ %3 = load i32, ptr %2, align 4
+ %call1 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef signext %3)
+ call void @recover()
+ call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %4 = load ptr, ptr %local_var, align 8
+ %5 = load i32, ptr %4, align 4
+ %call2 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3, i32 noundef signext %5)
+ %6 = load ptr, ptr %local_var, align 8
+ store i32 20, ptr %6, align 4
+ %7 = load ptr, ptr %local_var, align 8
+ %8 = load i32, ptr %7, align 4
+ %call3 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4, i32 noundef signext %8)
+ call void @foo()
+ %9 = load ptr, ptr %local_var, align 8
+ %10 = load i32, ptr %9, align 4
+ %call4 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5, i32 noundef signext %10)
+ ret i32 0
+}
+
+; Function Attrs: nounwind allocsize(0)
+declare noalias ptr @malloc(i64 noundef) #3
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: noreturn nounwind
+declare void @exit(i32 noundef signext) #5
+
+attributes #0 = { noinline nounwind optnone "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind allocsize(0) "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { noreturn nounwind "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-02-o0.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-02-o0.ll
new file mode 100644
index 00000000000000..ccad044dbeff52
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-02-o0.ll
@@ -0,0 +1,147 @@
+; -mbackchain
+; Non-volatile local malloc'd variable being modified between setjmp and longjmp call.
+; This test is without optimization -O0, modified value persists.
+; FIXME: Add this test case when local malloc'd non-volatile variable is fixed.
+; It will create infinite loop.
+
+; RUN: clang -O0 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+; CHECK: setjmp has been called local_var=30
+; CHECK: Calling function foo local_var=40
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=40
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-local-02.c'
+source_filename = "builtin-setjmp-longjmp-malloc-local-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at .str = private unnamed_addr constant [42 x i8] c"Calling longjmp from inside function foo\0A\00", align 2
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.1 = private unnamed_addr constant [29 x i8] c"Performing function recover\0A\00", align 2
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at .str.5 = private unnamed_addr constant [50 x i8] c"This point should never be reached local_var=%d \0A\00", align 2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @foo() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str)
+ call void @llvm.eh.sjlj.longjmp(ptr @buf)
+ unreachable
+}
+
+declare signext i32 @printf(ptr noundef, ...) #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline nounwind optnone
+define dso_local void @recover() #0 {
+entry:
+ %call = call signext i32 (ptr, ...) @printf(ptr noundef @.str.1)
+ ret void
+}
+
+; Function Attrs: noinline nounwind optnone
+define dso_local signext i32 @main() #0 {
+entry:
+ %retval = alloca i32, align 4
+ %local_var = alloca ptr, align 8
+ store i32 0, ptr %retval, align 4
+ %call = call noalias ptr @malloc(i64 noundef 4) #7
+ store ptr %call, ptr %local_var, align 8
+ %0 = load ptr, ptr %local_var, align 8
+ store i32 10, ptr %0, align 4
+ %1 = call i32 @llvm.eh.sjlj.setjmp(ptr @buf)
+ %cmp = icmp ne i32 %1, 0
+ br i1 %cmp, label %if.then, label %if.end4
+
+if.then: ; preds = %entry
+ %2 = load ptr, ptr %local_var, align 8
+ %3 = load i32, ptr %2, align 4
+ %call1 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef signext %3)
+ call void @recover()
+ %4 = load ptr, ptr %local_var, align 8
+ %5 = load i32, ptr %4, align 4
+ %cmp2 = icmp ne i32 %5, 20
+ br i1 %cmp2, label %if.then3, label %if.end
+
+if.then3: ; preds = %if.then
+ %6 = load ptr, ptr %local_var, align 8
+ call void @free(ptr noundef %6) #4
+ call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %if.then
+ %7 = load ptr, ptr %local_var, align 8
+ store i32 30, ptr %7, align 4
+ br label %if.end4
+
+if.end4: ; preds = %if.end, %entry
+ %8 = load ptr, ptr %local_var, align 8
+ %9 = load i32, ptr %8, align 4
+ %call5 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.3, i32 noundef signext %9)
+ %10 = load ptr, ptr %local_var, align 8
+ %11 = load i32, ptr %10, align 4
+ %cmp6 = icmp eq i32 %11, 10
+ br i1 %cmp6, label %if.then7, label %if.else
+
+if.then7: ; preds = %if.end4
+ %12 = load ptr, ptr %local_var, align 8
+ store i32 20, ptr %12, align 4
+ br label %if.end8
+
+if.else: ; preds = %if.end4
+ %13 = load ptr, ptr %local_var, align 8
+ store i32 40, ptr %13, align 4
+ br label %if.end8
+
+if.end8: ; preds = %if.else, %if.then7
+ %14 = load ptr, ptr %local_var, align 8
+ %15 = load i32, ptr %14, align 4
+ %call9 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.4, i32 noundef signext %15)
+ call void @foo()
+ %16 = load ptr, ptr %local_var, align 8
+ %17 = load i32, ptr %16, align 4
+ %call10 = call signext i32 (ptr, ...) @printf(ptr noundef @.str.5, i32 noundef signext %17)
+ ret i32 0
+}
+
+; Function Attrs: nounwind allocsize(0)
+declare noalias ptr @malloc(i64 noundef) #3
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #4
+
+; Function Attrs: nounwind
+declare void @free(ptr noundef) #5
+
+; Function Attrs: noreturn nounwind
+declare void @exit(i32 noundef signext) #6
+
+attributes #0 = { noinline nounwind optnone "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nounwind allocsize(0) "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { nounwind }
+attributes #5 = { nounwind "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { noreturn nounwind "backchain" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"frame-pointer", i32 2}
+!4 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-03.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-03.ll
new file mode 100644
index 00000000000000..c847026abbda0e
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-local-backchain-03.ll
@@ -0,0 +1,393 @@
+; -mbackchain
+; Non-volatile local malloc'd variable being modified between setjmp and longjmp call.
+; size of malloc is 25 and array variable is not kept on stack.
+; This test is with optimization -O2, modified value persists.
+; For size of malloc 20, all array values are stored to stack, and modified
+; values does not persist.
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: Returned from func4
+; CHECK: arr: 0
+; CHECK: arr: 2
+; CHECK: arr: 6
+; CHECK: arr: 12
+; CHECK: arr: 20
+; CHECK: arr: 30
+; CHECK: arr: 42
+; CHECK: arr: 56
+; CHECK: arr: 72
+; CHECK: arr: 90
+; CHECK: arr: 110
+; CHECK: arr: 132
+; CHECK: arr: 156
+; CHECK: arr: 182
+; CHECK: arr: 210
+; CHECK: arr: 240
+; CHECK: arr: 272
+; CHECK: arr: 306
+; CHECK: arr: 342
+; CHECK: arr: 380
+; CHECK: arr: 420
+; CHECK: arr: 462
+; CHECK: arr: 506
+; CHECK: arr: 552
+; CHECK: arr: 600
+; CHECK: In func3
+; CHECK: Returned from func3
+; CHECK: arr: 0
+; CHECK: arr: 3
+; CHECK: arr: 14
+; CHECK: arr: 39
+; CHECK: arr: 84
+; CHECK: arr: 155
+; CHECK: arr: 258
+; CHECK: arr: 399
+; CHECK: arr: 584
+; CHECK: arr: 819
+; CHECK: arr: 1110
+; CHECK: arr: 1463
+; CHECK: arr: 1884
+; CHECK: arr: 2379
+; CHECK: arr: 2954
+; CHECK: arr: 3615
+; CHECK: arr: 4368
+; CHECK: arr: 5219
+; CHECK: arr: 6174
+; CHECK: arr: 7239
+; CHECK: arr: 8420
+; CHECK: arr: 9723
+; CHECK: arr: 11154
+; CHECK: arr: 12719
+; CHECK: arr: 14424
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-local-03.c'
+source_filename = "builtin-setjmp-longjmp-malloc-local-03.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf3 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf2 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at buf1 = dso_local global [10 x ptr] zeroinitializer, align 8
+ at .str.6 = private unnamed_addr constant [9 x i8] c"arr: %d\0A\00", align 2
+ at str = private unnamed_addr constant [9 x i8] c"In func4\00", align 1
+ at str.10 = private unnamed_addr constant [9 x i8] c"In func3\00", align 1
+ at str.11 = private unnamed_addr constant [9 x i8] c"In func2\00", align 1
+ at str.12 = private unnamed_addr constant [20 x i8] c"Returned from func3\00", align 1
+ at str.13 = private unnamed_addr constant [32 x i8] c"First __builtin_setjmp in func1\00", align 1
+ at str.14 = private unnamed_addr constant [20 x i8] c"Returned from func4\00", align 1
+ at str.15 = private unnamed_addr constant [33 x i8] c"Second __builtin_setjmp in func1\00", align 1
+ at str.16 = private unnamed_addr constant [44 x i8] c"In main, after __builtin_longjmp from func1\00", align 1
+ at str.17 = private unnamed_addr constant [20 x i8] c"In main, first time\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func4() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf3)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func3() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.10)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf2)
+ unreachable
+}
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @func2() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.11)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf1)
+ unreachable
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @func1() local_unnamed_addr #3 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(100) ptr @malloc(i64 noundef 100) #9
+ store i32 0, ptr %call, align 4, !tbaa !4
+ %arrayidx.1 = getelementptr inbounds i8, ptr %call, i64 4
+ store i32 2, ptr %arrayidx.1, align 4, !tbaa !4
+ %arrayidx.2 = getelementptr inbounds i8, ptr %call, i64 8
+ store i32 6, ptr %arrayidx.2, align 4, !tbaa !4
+ %arrayidx.3 = getelementptr inbounds i8, ptr %call, i64 12
+ store i32 12, ptr %arrayidx.3, align 4, !tbaa !4
+ %arrayidx.4 = getelementptr inbounds i8, ptr %call, i64 16
+ store i32 20, ptr %arrayidx.4, align 4, !tbaa !4
+ %arrayidx.5 = getelementptr inbounds i8, ptr %call, i64 20
+ store i32 30, ptr %arrayidx.5, align 4, !tbaa !4
+ %arrayidx.6 = getelementptr inbounds i8, ptr %call, i64 24
+ store i32 42, ptr %arrayidx.6, align 4, !tbaa !4
+ %arrayidx.7 = getelementptr inbounds i8, ptr %call, i64 28
+ store i32 56, ptr %arrayidx.7, align 4, !tbaa !4
+ %arrayidx.8 = getelementptr inbounds i8, ptr %call, i64 32
+ store i32 72, ptr %arrayidx.8, align 4, !tbaa !4
+ %arrayidx.9 = getelementptr inbounds i8, ptr %call, i64 36
+ store i32 90, ptr %arrayidx.9, align 4, !tbaa !4
+ %arrayidx.10 = getelementptr inbounds i8, ptr %call, i64 40
+ store i32 110, ptr %arrayidx.10, align 4, !tbaa !4
+ %arrayidx.11 = getelementptr inbounds i8, ptr %call, i64 44
+ store i32 132, ptr %arrayidx.11, align 4, !tbaa !4
+ %arrayidx.12 = getelementptr inbounds i8, ptr %call, i64 48
+ store i32 156, ptr %arrayidx.12, align 4, !tbaa !4
+ %arrayidx.13 = getelementptr inbounds i8, ptr %call, i64 52
+ store i32 182, ptr %arrayidx.13, align 4, !tbaa !4
+ %arrayidx.14 = getelementptr inbounds i8, ptr %call, i64 56
+ store i32 210, ptr %arrayidx.14, align 4, !tbaa !4
+ %arrayidx.15 = getelementptr inbounds i8, ptr %call, i64 60
+ store i32 240, ptr %arrayidx.15, align 4, !tbaa !4
+ %arrayidx.16 = getelementptr inbounds i8, ptr %call, i64 64
+ store i32 272, ptr %arrayidx.16, align 4, !tbaa !4
+ %arrayidx.17 = getelementptr inbounds i8, ptr %call, i64 68
+ store i32 306, ptr %arrayidx.17, align 4, !tbaa !4
+ %arrayidx.18 = getelementptr inbounds i8, ptr %call, i64 72
+ store i32 342, ptr %arrayidx.18, align 4, !tbaa !4
+ %arrayidx.19 = getelementptr inbounds i8, ptr %call, i64 76
+ store i32 380, ptr %arrayidx.19, align 4, !tbaa !4
+ %arrayidx.20 = getelementptr inbounds i8, ptr %call, i64 80
+ store i32 420, ptr %arrayidx.20, align 4, !tbaa !4
+ %arrayidx.21 = getelementptr inbounds i8, ptr %call, i64 84
+ store i32 462, ptr %arrayidx.21, align 4, !tbaa !4
+ %arrayidx.22 = getelementptr inbounds i8, ptr %call, i64 88
+ store i32 506, ptr %arrayidx.22, align 4, !tbaa !4
+ %arrayidx.23 = getelementptr inbounds i8, ptr %call, i64 92
+ store i32 552, ptr %arrayidx.23, align 4, !tbaa !4
+ %arrayidx.24 = getelementptr inbounds i8, ptr %call, i64 96
+ store i32 600, ptr %arrayidx.24, align 4, !tbaa !4
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf2)
+ %cmp3 = icmp eq i32 %0, 0
+ br i1 %cmp3, label %if.then, label %if.else39
+
+if.then: ; preds = %entry
+ %puts79 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.13)
+ %1 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf3)
+ %cmp6 = icmp eq i32 %1, 0
+ br i1 %cmp6, label %if.then8, label %if.else
+
+if.then8: ; preds = %if.then
+ %puts84 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.15)
+ tail call void @func4()
+ unreachable
+
+if.else: ; preds = %if.then
+ %puts80 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.14)
+ %2 = load i32, ptr %call, align 4, !tbaa !4
+ %call19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %2)
+ %3 = load i32, ptr %arrayidx.1, align 4, !tbaa !4
+ %call19.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %3)
+ %4 = load i32, ptr %arrayidx.2, align 4, !tbaa !4
+ %call19.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %4)
+ %5 = load i32, ptr %arrayidx.3, align 4, !tbaa !4
+ %call19.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %5)
+ %6 = load i32, ptr %arrayidx.4, align 4, !tbaa !4
+ %call19.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %6)
+ %7 = load i32, ptr %arrayidx.5, align 4, !tbaa !4
+ %call19.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %7)
+ %8 = load i32, ptr %arrayidx.6, align 4, !tbaa !4
+ %call19.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %8)
+ %9 = load i32, ptr %arrayidx.7, align 4, !tbaa !4
+ %call19.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %9)
+ %10 = load i32, ptr %arrayidx.8, align 4, !tbaa !4
+ %call19.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %10)
+ %11 = load i32, ptr %arrayidx.9, align 4, !tbaa !4
+ %call19.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %11)
+ %12 = load i32, ptr %arrayidx.10, align 4, !tbaa !4
+ %call19.10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %12)
+ %13 = load i32, ptr %arrayidx.11, align 4, !tbaa !4
+ %call19.11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %13)
+ %14 = load i32, ptr %arrayidx.12, align 4, !tbaa !4
+ %call19.12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %14)
+ %15 = load i32, ptr %arrayidx.13, align 4, !tbaa !4
+ %call19.13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %15)
+ %16 = load i32, ptr %arrayidx.14, align 4, !tbaa !4
+ %call19.14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %16)
+ %17 = load i32, ptr %arrayidx.15, align 4, !tbaa !4
+ %call19.15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %17)
+ %18 = load i32, ptr %arrayidx.16, align 4, !tbaa !4
+ %call19.16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %18)
+ %19 = load i32, ptr %arrayidx.17, align 4, !tbaa !4
+ %call19.17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %19)
+ %20 = load i32, ptr %arrayidx.18, align 4, !tbaa !4
+ %call19.18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %20)
+ %21 = load i32, ptr %arrayidx.19, align 4, !tbaa !4
+ %call19.19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %21)
+ %22 = load i32, ptr %arrayidx.20, align 4, !tbaa !4
+ %call19.20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %22)
+ %23 = load i32, ptr %arrayidx.21, align 4, !tbaa !4
+ %call19.21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %23)
+ %24 = load i32, ptr %arrayidx.22, align 4, !tbaa !4
+ %call19.22 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %24)
+ %25 = load i32, ptr %arrayidx.23, align 4, !tbaa !4
+ %call19.23 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %25)
+ %26 = load i32, ptr %arrayidx.24, align 4, !tbaa !4
+ %call19.24 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %26)
+ br label %for.body28
+
+for.cond.cleanup27: ; preds = %for.body28
+ tail call void @func3()
+ unreachable
+
+for.body28: ; preds = %for.body28, %if.else
+ %indvars.iv = phi i64 [ 0, %if.else ], [ %indvars.iv.next.4, %for.body28 ]
+ %indvars96 = trunc i64 %indvars.iv to i32
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %indvars = trunc i64 %indvars.iv.next to i32
+ %mul3081 = mul nuw nsw i32 %indvars, %indvars96
+ %add3283 = add nuw nsw i32 %mul3081, 1
+ %add33 = mul nuw nsw i32 %add3283, %indvars96
+ %arrayidx35 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv
+ store i32 %add33, ptr %arrayidx35, align 4, !tbaa !4
+ %indvars96.1 = trunc i64 %indvars.iv.next to i32
+ %indvars.iv.next.1 = add nuw nsw i64 %indvars.iv, 2
+ %indvars.1 = trunc i64 %indvars.iv.next.1 to i32
+ %mul3081.1 = mul nuw nsw i32 %indvars.1, %indvars96.1
+ %add3283.1 = add nuw nsw i32 %mul3081.1, 1
+ %add33.1 = mul nuw nsw i32 %add3283.1, %indvars96.1
+ %arrayidx35.1 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv.next
+ store i32 %add33.1, ptr %arrayidx35.1, align 4, !tbaa !4
+ %indvars96.2 = trunc i64 %indvars.iv.next.1 to i32
+ %indvars.iv.next.2 = add nuw nsw i64 %indvars.iv, 3
+ %indvars.2 = trunc i64 %indvars.iv.next.2 to i32
+ %mul3081.2 = mul nuw nsw i32 %indvars.2, %indvars96.2
+ %add3283.2 = add nuw nsw i32 %mul3081.2, 1
+ %add33.2 = mul nuw nsw i32 %add3283.2, %indvars96.2
+ %arrayidx35.2 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv.next.1
+ store i32 %add33.2, ptr %arrayidx35.2, align 4, !tbaa !4
+ %indvars96.3 = trunc i64 %indvars.iv.next.2 to i32
+ %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4
+ %indvars.3 = trunc i64 %indvars.iv.next.3 to i32
+ %mul3081.3 = mul nuw nsw i32 %indvars.3, %indvars96.3
+ %add3283.3 = add nuw nsw i32 %mul3081.3, 1
+ %add33.3 = mul nuw nsw i32 %add3283.3, %indvars96.3
+ %arrayidx35.3 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv.next.2
+ store i32 %add33.3, ptr %arrayidx35.3, align 4, !tbaa !4
+ %indvars96.4 = trunc i64 %indvars.iv.next.3 to i32
+ %indvars.iv.next.4 = add nuw nsw i64 %indvars.iv, 5
+ %indvars.4 = trunc i64 %indvars.iv.next.4 to i32
+ %mul3081.4 = mul nuw nsw i32 %indvars.4, %indvars96.4
+ %add3283.4 = add nuw nsw i32 %mul3081.4, 1
+ %add33.4 = mul nuw nsw i32 %add3283.4, %indvars96.4
+ %arrayidx35.4 = getelementptr inbounds i32, ptr %call, i64 %indvars.iv.next.3
+ store i32 %add33.4, ptr %arrayidx35.4, align 4, !tbaa !4
+ %exitcond.not.4 = icmp eq i64 %indvars.iv.next.4, 25
+ br i1 %exitcond.not.4, label %for.cond.cleanup27, label %for.body28, !llvm.loop !8
+
+if.else39: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.12)
+ %27 = load i32, ptr %call, align 4, !tbaa !4
+ %call49 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %27)
+ %28 = load i32, ptr %arrayidx.1, align 4, !tbaa !4
+ %call49.1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %28)
+ %29 = load i32, ptr %arrayidx.2, align 4, !tbaa !4
+ %call49.2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %29)
+ %30 = load i32, ptr %arrayidx.3, align 4, !tbaa !4
+ %call49.3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %30)
+ %31 = load i32, ptr %arrayidx.4, align 4, !tbaa !4
+ %call49.4 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %31)
+ %32 = load i32, ptr %arrayidx.5, align 4, !tbaa !4
+ %call49.5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %32)
+ %33 = load i32, ptr %arrayidx.6, align 4, !tbaa !4
+ %call49.6 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %33)
+ %34 = load i32, ptr %arrayidx.7, align 4, !tbaa !4
+ %call49.7 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %34)
+ %35 = load i32, ptr %arrayidx.8, align 4, !tbaa !4
+ %call49.8 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %35)
+ %36 = load i32, ptr %arrayidx.9, align 4, !tbaa !4
+ %call49.9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %36)
+ %37 = load i32, ptr %arrayidx.10, align 4, !tbaa !4
+ %call49.10 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %37)
+ %38 = load i32, ptr %arrayidx.11, align 4, !tbaa !4
+ %call49.11 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %38)
+ %39 = load i32, ptr %arrayidx.12, align 4, !tbaa !4
+ %call49.12 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %39)
+ %40 = load i32, ptr %arrayidx.13, align 4, !tbaa !4
+ %call49.13 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %40)
+ %41 = load i32, ptr %arrayidx.14, align 4, !tbaa !4
+ %call49.14 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %41)
+ %42 = load i32, ptr %arrayidx.15, align 4, !tbaa !4
+ %call49.15 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %42)
+ %43 = load i32, ptr %arrayidx.16, align 4, !tbaa !4
+ %call49.16 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %43)
+ %44 = load i32, ptr %arrayidx.17, align 4, !tbaa !4
+ %call49.17 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %44)
+ %45 = load i32, ptr %arrayidx.18, align 4, !tbaa !4
+ %call49.18 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %45)
+ %46 = load i32, ptr %arrayidx.19, align 4, !tbaa !4
+ %call49.19 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %46)
+ %47 = load i32, ptr %arrayidx.20, align 4, !tbaa !4
+ %call49.20 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %47)
+ %48 = load i32, ptr %arrayidx.21, align 4, !tbaa !4
+ %call49.21 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %48)
+ %49 = load i32, ptr %arrayidx.22, align 4, !tbaa !4
+ %call49.22 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %49)
+ %50 = load i32, ptr %arrayidx.23, align 4, !tbaa !4
+ %call49.23 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %50)
+ %51 = load i32, ptr %arrayidx.24, align 4, !tbaa !4
+ %call49.24 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.6, i32 noundef signext %51)
+ tail call void @free(ptr noundef nonnull %call) #5
+ tail call void @func2()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #4
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #5
+
+; Function Attrs: mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite)
+declare void @free(ptr allocptr nocapture noundef) local_unnamed_addr #6
+
+; Function Attrs: nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #7 {
+entry:
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf1)
+ %cmp = icmp eq i32 %0, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ %puts3 = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.17)
+ %call1 = tail call signext i32 @func1()
+ unreachable
+
+if.else: ; preds = %entry
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.16)
+ ret i32 0
+}
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #8
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { nounwind }
+attributes #6 = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #7 = { nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree nounwind }
+attributes #9 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = distinct !{!8, !9}
+!9 = !{!"llvm.loop.mustprogress"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-01-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-01-o2.ll
new file mode 100644
index 00000000000000..ae875c8d2c7fba
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-01-o2.ll
@@ -0,0 +1,104 @@
+; volatile local malloc'd variable being modified between setjmp and longjmp call.
+; modified value persists.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-volatile-01.c'
+source_filename = "builtin-setjmp-longjmp-malloc-volatile-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(4) ptr @malloc(i64 noundef 4) #9
+ store volatile i32 10, ptr %call, align 4, !tbaa !4
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ %1 = load volatile i32, ptr %call, align 4, !tbaa !4
+ br i1 %cmp.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %1)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %1)
+ store volatile i32 20, ptr %call, align 4, !tbaa !4
+ %2 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %2)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #5
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #6
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #7
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #8
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind }
+attributes #7 = { nofree noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree nounwind }
+attributes #9 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-02-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-02-o2.ll
new file mode 100644
index 00000000000000..74b6bd33fc965a
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-02-o2.ll
@@ -0,0 +1,122 @@
+; volatile local malloc'd variable being modified between setjmp and longjmp call.
+; modified value persists.
+
+; RUN: clang -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+; CHECK: setjmp has been called local_var=30
+; CHECK: Calling function foo local_var=40
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=40
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-volatile-02.c'
+source_filename = "builtin-setjmp-longjmp-malloc-volatile-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(4) ptr @malloc(i64 noundef 4) #9
+ store volatile i32 10, ptr %call, align 4, !tbaa !4
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ br i1 %cmp.not, label %if.end4, label %if.then
+
+if.then: ; preds = %entry
+ %1 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %1)
+ tail call void @recover()
+ %2 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %cmp2.not = icmp eq i32 %2, 20
+ br i1 %cmp2.not, label %if.end, label %if.then3
+
+if.then3: ; preds = %if.then
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %if.then
+ store volatile i32 30, ptr %call, align 4, !tbaa !4
+ br label %if.end4
+
+if.end4: ; preds = %if.end, %entry
+ %3 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %3)
+ %4 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %cmp6 = icmp eq i32 %4, 10
+ %. = select i1 %cmp6, i32 20, i32 40
+ store volatile i32 %., ptr %call, align 4, !tbaa !4
+ %5 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %5)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #5
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #6
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #7
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #8
+
+attributes #0 = { noinline noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind }
+attributes #7 = { nofree noreturn nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree nounwind }
+attributes #9 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-backchain-01-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-backchain-01-o2.ll
new file mode 100644
index 00000000000000..f6267f8b3d6308
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-backchain-01-o2.ll
@@ -0,0 +1,105 @@
+; -mbackchain
+; volatile local malloc'd variable being modified between setjmp and longjmp call.
+; modified value persists.
+
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-volatile-01.c'
+source_filename = "builtin-setjmp-longjmp-malloc-volatile-01.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(4) ptr @malloc(i64 noundef 4) #9
+ store volatile i32 10, ptr %call, align 4, !tbaa !4
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ %1 = load volatile i32, ptr %call, align 4, !tbaa !4
+ br i1 %cmp.not, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %1)
+ tail call void @recover()
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %entry
+ %call2 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %1)
+ store volatile i32 20, ptr %call, align 4, !tbaa !4
+ %2 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %call3 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %2)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #5
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #6
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #7
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #8
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind }
+attributes #7 = { nofree noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree nounwind }
+attributes #9 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
diff --git a/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-backchain-02-o2.ll b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-backchain-02-o2.ll
new file mode 100644
index 00000000000000..12c417ff2987b6
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/builtin-setjmp-longjmp-malloc-volatile-backchain-02-o2.ll
@@ -0,0 +1,124 @@
+; -mbackchain
+; volatile local malloc'd variable being modified between setjmp and longjmp call.
+; modified value persists.
+
+; RUN: clang -mbackchain -O2 -o %t %s
+; RUN: %t | FileCheck %s
+
+; CHECK: setjmp has been called local_var=10
+; CHECK: Calling function foo local_var=20
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=20
+; CHECK: Performing function recover
+; CHECK: setjmp has been called local_var=30
+; CHECK: Calling function foo local_var=40
+; CHECK: Calling longjmp from inside function foo
+; CHECK: longjmp has been called local_val=40
+; CHECK: Performing function recover
+
+
+; ModuleID = 'builtin-setjmp-longjmp-malloc-volatile-02.c'
+source_filename = "builtin-setjmp-longjmp-malloc-volatile-02.c"
+target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-unknown-linux-gnu"
+
+ at buf = dso_local global [20 x ptr] zeroinitializer, align 8
+ at .str.2 = private unnamed_addr constant [39 x i8] c"longjmp has been called local_val=%d \0A\00", align 2
+ at .str.3 = private unnamed_addr constant [38 x i8] c"setjmp has been called local_var=%d \0A\00", align 2
+ at .str.4 = private unnamed_addr constant [36 x i8] c"Calling function foo local_var=%d \0A\00", align 2
+ at str = private unnamed_addr constant [41 x i8] c"Calling longjmp from inside function foo\00", align 1
+ at str.6 = private unnamed_addr constant [28 x i8] c"Performing function recover\00", align 1
+
+; Function Attrs: noinline noreturn nounwind
+define dso_local void @foo() local_unnamed_addr #0 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str)
+ tail call void @llvm.eh.sjlj.longjmp(ptr nonnull @buf)
+ unreachable
+}
+
+; Function Attrs: nofree nounwind
+declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #1
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.eh.sjlj.longjmp(ptr) #2
+
+; Function Attrs: nofree noinline nounwind
+define dso_local void @recover() local_unnamed_addr #3 {
+entry:
+ %puts = tail call i32 @puts(ptr nonnull dereferenceable(1) @str.6)
+ ret void
+}
+
+; Function Attrs: noreturn nounwind
+define dso_local noundef signext i32 @main() local_unnamed_addr #4 {
+entry:
+ %call = tail call noalias dereferenceable_or_null(4) ptr @malloc(i64 noundef 4) #9
+ store volatile i32 10, ptr %call, align 4, !tbaa !4
+ %0 = tail call i32 @llvm.eh.sjlj.setjmp(ptr nonnull @buf)
+ %cmp.not = icmp eq i32 %0, 0
+ br i1 %cmp.not, label %if.end4, label %if.then
+
+if.then: ; preds = %entry
+ %1 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %call1 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.2, i32 noundef signext %1)
+ tail call void @recover()
+ %2 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %cmp2.not = icmp eq i32 %2, 20
+ br i1 %cmp2.not, label %if.end, label %if.then3
+
+if.then3: ; preds = %if.then
+ tail call void @exit(i32 noundef signext 0) #2
+ unreachable
+
+if.end: ; preds = %if.then
+ store volatile i32 30, ptr %call, align 4, !tbaa !4
+ br label %if.end4
+
+if.end4: ; preds = %if.end, %entry
+ %3 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %call5 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.3, i32 noundef signext %3)
+ %4 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %cmp6 = icmp eq i32 %4, 10
+ %. = select i1 %cmp6, i32 20, i32 40
+ store volatile i32 %., ptr %call, align 4, !tbaa !4
+ %5 = load volatile i32, ptr %call, align 4, !tbaa !4
+ %call9 = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.4, i32 noundef signext %5)
+ tail call void @foo()
+ unreachable
+}
+
+; Function Attrs: mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite)
+declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #5
+
+; Function Attrs: nounwind
+declare i32 @llvm.eh.sjlj.setjmp(ptr) #6
+
+; Function Attrs: nofree noreturn nounwind
+declare void @exit(i32 noundef signext) local_unnamed_addr #7
+
+; Function Attrs: nofree nounwind
+declare noundef i32 @puts(ptr nocapture noundef readonly) local_unnamed_addr #8
+
+attributes #0 = { noinline noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #1 = { nofree nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #2 = { noreturn nounwind }
+attributes #3 = { nofree noinline nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #4 = { noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #5 = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #6 = { nounwind }
+attributes #7 = { nofree noreturn nounwind "backchain" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="z10" }
+attributes #8 = { nofree nounwind }
+attributes #9 = { nounwind allocsize(0) }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git a0433728375e658551506ce43b0848200fdd6e61)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
>From 2a5bd18d2c90114e682261dc1597e547fe346feb Mon Sep 17 00:00:00 2001
From: anoopkg6 <anoop.kumar6 at ibm.com>
Date: Fri, 22 Nov 2024 19:46:05 +0100
Subject: [PATCH 8/9] Incorporated code-review changes
---
clang/lib/CodeGen/CGBuiltin.cpp | 2 +
.../Target/SystemZ/SystemZISelLowering.cpp | 39 +++++++++++--------
llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 21 +++++-----
3 files changed, 36 insertions(+), 26 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1de6aded302ceb..f3da6305bbd184 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4621,6 +4621,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
if (getTarget().getTriple().getArch() == llvm::Triple::systemz) {
// Call LLVM's EH setjmp, which is lightweight.
+ // We're not filling any fields of the jmp_buf here and leave
+ // it all to the back-end.
Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this)));
}
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index f498f9eab865f1..881fe67360fb2e 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -756,8 +756,6 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
-
-
// We want to use MVC in preference to even a single load/store pair.
MaxStoresPerMemcpy = Subtarget.hasVector() ? 2 : 0;
MaxStoresPerMemcpyOptSize = 0;
@@ -1024,40 +1022,41 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
// thisMBB:
+ const int64_t FPOffset = 0; // Slot 1.
const int64_t LabelOffset = 1 * PVT.getStoreSize(); // Slot 2.
+ const int64_t BCOffset = 2 * PVT.getStoreSize(); // Slot 3.
const int64_t SPOffset = 3 * PVT.getStoreSize(); // Slot 4.
// Buf address.
Register BufReg = MI.getOperand(1).getReg();
- unsigned LabelReg = 0;
const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
- LabelReg = MRI.createVirtualRegister(PtrRC);
+ unsigned LabelReg = MRI.createVirtualRegister(PtrRC);
- // prepare IP for longjmp.
+ // Prepare IP for longjmp.
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LARL), LabelReg)
.addMBB(restoreMBB);
- // store IP for return from jmp, slot 2, offset = 1.
+ // Store IP for return from jmp, slot 2, offset = 1.
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
.addReg(LabelReg)
.addReg(BufReg)
.addImm(LabelOffset)
.addReg(0);
- bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
+ auto *SpecialRegs = Subtarget.getSpecialRegisters();
+ bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
if (HasFP) {
- const int64_t FPOffset = 0;
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
- .addReg(SystemZ::R11D)
+ .addReg(SpecialRegs->getFramePointerRegister())
.addReg(BufReg)
.addImm(FPOffset)
.addReg(0);
}
- // store SP.
+ // Store SP.
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
- .addReg(SystemZ::R15D)
+ .addReg(SpecialRegs->getStackPointerRegister())
.addReg(BufReg)
.addImm(SPOffset)
.addReg(0);
@@ -1065,10 +1064,9 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
// Slot 3(Offset = 2) Backchain value (if building with -mbackchain).
bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain();
if (BackChain) {
- const int64_t BCOffset = 2 * PVT.getStoreSize();
Register BCReg = MRI.createVirtualRegister(RC);
MIB = BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LG), BCReg)
- .addReg(SystemZ::R15D)
+ .addReg(SpecialRegs->getStackPointerRegister())
.addImm(0)
.addReg(0);
@@ -1125,6 +1123,7 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
"Invalid Pointer Size!");
Register BufReg = MI.getOperand(0).getReg();
const TargetRegisterClass *RC = MRI.getRegClass(BufReg);
+ auto *SpecialRegs = Subtarget.getSpecialRegisters();
Register Tmp = MRI.createVirtualRegister(RC);
Register BCReg = MRI.createVirtualRegister(RC);
@@ -1141,7 +1140,8 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
.addImm(LabelOffset)
.addReg(0);
- MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R11D)
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG),
+ SpecialRegs->getFramePointerRegister())
.addReg(BufReg)
.addImm(FPOffset)
.addReg(0);
@@ -1163,7 +1163,8 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
.addReg(0);
}
- MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG), SystemZ::R15D)
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG),
+ SpecialRegs->getStackPointerRegister())
.addReg(BufReg)
.addImm(SPOffset)
.addReg(0);
@@ -1171,7 +1172,7 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
if (BackChain) {
BuildMI(*MBB, MI, DL, TII->get(SystemZ::STG))
.addReg(BCReg)
- .addReg(SystemZ::R15D)
+ .addReg(SpecialRegs->getStackPointerRegister())
.addImm(0)
.addReg(0);
}
@@ -1182,7 +1183,7 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
return MBB;
}
-// Returns true if stack probing through inline assembly is requested.
+/// Returns true if stack probing through inline assembly is requested.
bool SystemZTargetLowering::hasInlineStackProbe(const MachineFunction &MF) const {
// If the function specifically requests inline stack probes, emit them.
if (MF.getFunction().hasFnAttribute("probe-stack"))
@@ -6536,6 +6537,10 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
return lowerREADCYCLECOUNTER(Op, DAG);
case ISD::EH_SJLJ_SETJMP:
case ISD::EH_SJLJ_LONGJMP:
+ // These operations action are Legal now, not Custom. The reason we need
+ // to keep it here is that common code treats these Pseudos as Custom,
+ // and expands them using EmitInstrWithCustomInserter in FinalizeISel.cpp
+ // after ISel.
return Op;
default:
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index ad7ee522a8c6f7..44c75cac68a86d 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -1874,17 +1874,20 @@ let mayLoad = 1, mayStore = 1, Defs = [CC] in {
//--------------------------------------------------------------------------
// Setjmp/Longjmp.
//--------------------------------------------------------------------------
-let isTerminator = 1, isBarrier = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1, Size = 0 in {
- def EH_SjLj_Setup : Pseudo<(outs), (ins brtarget32:$dst), []>;
-}
-
-let hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
- def EH_SjLj_SetJmp : Pseudo<(outs GR32:$dst), (ins ADDR64:$R2), [(set GR32:$dst, (z_eh_sjlj_setjmp ADDR64:$R2))]>;
+let isBarrier = 1, hasNoSchedulingInfo = 1 in {
+ let hasSideEffects = 1, usesCustomInserter = 1 in {
+ def EH_SjLj_SetJmp : Pseudo<(outs GR32:$dst), (ins ADDR64:$R2),
+ [(set GR32:$dst, (z_eh_sjlj_setjmp ADDR64:$R2))]>;
+ let isTerminator = 1 in {
+ def EH_SjLj_LongJmp : Pseudo<(outs), (ins ADDR64:$R2),
+ [(z_eh_sjlj_longjmp ADDR64:$R2)]>;
+ }
+ }
+ let isTerminator = 1, isCodeGenOnly = 1, Size = 0 in {
+ def EH_SjLj_Setup : Pseudo<(outs), (ins brtarget32:$dst), []>;
+ }
}
-let hasSideEffects = 1, isTerminator = 1, isBarrier = 1, usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
- def EH_SjLj_LongJmp : Pseudo<(outs), (ins ADDR64:$R2), [(z_eh_sjlj_longjmp ADDR64:$R2)]>;
-}
//===----------------------------------------------------------------------===//
// Message-security assist
//===----------------------------------------------------------------------===//
>From 68aadd2b40af92594e78db98b4b5dba608768a2d Mon Sep 17 00:00:00 2001
From: anoopkg6 <anoop.kumar6 at ibm.com>
Date: Fri, 22 Nov 2024 19:51:39 +0100
Subject: [PATCH 9/9] Incorporated code-review changes.
---
clang/lib/CodeGen/CGBuiltin.cpp | 2 +-
.../Target/SystemZ/SystemZISelLowering.cpp | 78 +++++++++----------
.../SystemZ/builtin-longjmp-backchain-01.ll | 5 --
3 files changed, 40 insertions(+), 45 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f3da6305bbd184..363d01ad3c8f4a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4621,7 +4621,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
if (getTarget().getTriple().getArch() == llvm::Triple::systemz) {
// Call LLVM's EH setjmp, which is lightweight.
- // We're not filling any fields of the jmp_buf here and leave
+ // We're not filling any fields of the jmp_buf here and leave
// it all to the back-end.
Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this)));
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 881fe67360fb2e..15ee35252d5d74 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -1022,16 +1022,16 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
// thisMBB:
- const int64_t FPOffset = 0; // Slot 1.
+ const int64_t FPOffset = 0; // Slot 1.
const int64_t LabelOffset = 1 * PVT.getStoreSize(); // Slot 2.
- const int64_t BCOffset = 2 * PVT.getStoreSize(); // Slot 3.
+ const int64_t BCOffset = 2 * PVT.getStoreSize(); // Slot 3.
const int64_t SPOffset = 3 * PVT.getStoreSize(); // Slot 4.
// Buf address.
Register BufReg = MI.getOperand(1).getReg();
const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
- unsigned LabelReg = MRI.createVirtualRegister(PtrRC);
+ unsigned LabelReg = MRI.createVirtualRegister(PtrRC);
// Prepare IP for longjmp.
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LARL), LabelReg)
@@ -1047,34 +1047,34 @@ SystemZTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
auto *SpecialRegs = Subtarget.getSpecialRegisters();
bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
if (HasFP) {
- BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
- .addReg(SpecialRegs->getFramePointerRegister())
- .addReg(BufReg)
- .addImm(FPOffset)
- .addReg(0);
+ BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
+ .addReg(SpecialRegs->getFramePointerRegister())
+ .addReg(BufReg)
+ .addImm(FPOffset)
+ .addReg(0);
}
-
+
// Store SP.
BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
- .addReg(SpecialRegs->getStackPointerRegister())
- .addReg(BufReg)
- .addImm(SPOffset)
- .addReg(0);
+ .addReg(SpecialRegs->getStackPointerRegister())
+ .addReg(BufReg)
+ .addImm(SPOffset)
+ .addReg(0);
// Slot 3(Offset = 2) Backchain value (if building with -mbackchain).
bool BackChain = MF->getSubtarget<SystemZSubtarget>().hasBackChain();
if (BackChain) {
- Register BCReg = MRI.createVirtualRegister(RC);
- MIB = BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LG), BCReg)
- .addReg(SpecialRegs->getStackPointerRegister())
- .addImm(0)
- .addReg(0);
+ Register BCReg = MRI.createVirtualRegister(RC);
+ MIB = BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::LG), BCReg)
+ .addReg(SpecialRegs->getStackPointerRegister())
+ .addImm(0)
+ .addReg(0);
- BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
- .addReg(BCReg)
- .addReg(BufReg)
- .addImm(BCOffset)
- .addReg(0);
+ BuildMI(*thisMBB, MI, DL, TII->get(SystemZ::STG))
+ .addReg(BCReg)
+ .addReg(BufReg)
+ .addImm(BCOffset)
+ .addReg(0);
}
// Setup.
@@ -1140,11 +1140,11 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
.addImm(LabelOffset)
.addReg(0);
- MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG),
- SpecialRegs->getFramePointerRegister())
- .addReg(BufReg)
- .addImm(FPOffset)
- .addReg(0);
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG),
+ SpecialRegs->getFramePointerRegister())
+ .addReg(BufReg)
+ .addImm(FPOffset)
+ .addReg(0);
// We are restoring R13 even though we never stored in setjmp from llvm,
// as gcc always stores R13 in builtin_setjmp. We could have mixed code
@@ -1163,18 +1163,18 @@ SystemZTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
.addReg(0);
}
- MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG),
+ MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::LG),
SpecialRegs->getStackPointerRegister())
- .addReg(BufReg)
- .addImm(SPOffset)
- .addReg(0);
+ .addReg(BufReg)
+ .addImm(SPOffset)
+ .addReg(0);
if (BackChain) {
- BuildMI(*MBB, MI, DL, TII->get(SystemZ::STG))
- .addReg(BCReg)
- .addReg(SpecialRegs->getStackPointerRegister())
- .addImm(0)
- .addReg(0);
+ BuildMI(*MBB, MI, DL, TII->get(SystemZ::STG))
+ .addReg(BCReg)
+ .addReg(SpecialRegs->getStackPointerRegister())
+ .addImm(0)
+ .addReg(0);
}
MIB = BuildMI(*MBB, MI, DL, TII->get(SystemZ::BR)).addReg(Tmp);
@@ -6537,8 +6537,8 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
return lowerREADCYCLECOUNTER(Op, DAG);
case ISD::EH_SJLJ_SETJMP:
case ISD::EH_SJLJ_LONGJMP:
- // These operations action are Legal now, not Custom. The reason we need
- // to keep it here is that common code treats these Pseudos as Custom,
+ // These operations action are Legal now, not Custom. The reason we need
+ // to keep it here is that common code treats these Pseudos as Custom,
// and expands them using EmitInstrWithCustomInserter in FinalizeISel.cpp
// after ISel.
return Op;
diff --git a/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll b/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
index 39ee483c27cbd5..8758f68c08ab9e 100644
--- a/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
+++ b/llvm/test/CodeGen/SystemZ/builtin-longjmp-backchain-01.ll
@@ -7,11 +7,6 @@
; RUN: llc -O2 < %s | FileCheck %s
-; ModuleID = 'longjmp.c'
-source_filename = "longjmp.c"
-target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
-target triple = "s390x-unknown-linux-gnu"
-
@buf = dso_local global [20 x ptr] zeroinitializer, align 8
; Function Attrs: noreturn nounwind
More information about the cfe-commits
mailing list