mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[Sparc] Remove the support for builtin setjmp/longjmp
Summary: It is currently broken and for Sparc there is not much benefit in using a builtin version compared to a library version. Both versions needs to store the same four values in setjmp and flush the register windows in longjmp. If the need for a builtin setjmp/longjmp arises there is an improved implementation available at https://reviews.llvm.org/D50969. Reviewers: jyknight, joerg, venkatra Subscribers: fedor.sergeev, jrtc27, llvm-commits Differential Revision: https://reviews.llvm.org/D51487 llvm-svn: 343210
This commit is contained in:
parent
634d96e078
commit
e34c22f35a
@ -1545,9 +1545,6 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f128, Custom);
|
||||
|
||||
setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
|
||||
setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
|
||||
|
||||
setOperationAction(ISD::ADDC, MVT::i32, Custom);
|
||||
setOperationAction(ISD::ADDE, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SUBC, MVT::i32, Custom);
|
||||
@ -1828,8 +1825,6 @@ const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";
|
||||
case SPISD::SELECT_XCC: return "SPISD::SELECT_XCC";
|
||||
case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC";
|
||||
case SPISD::EH_SJLJ_SETJMP: return "SPISD::EH_SJLJ_SETJMP";
|
||||
case SPISD::EH_SJLJ_LONGJMP: return "SPISD::EH_SJLJ_LONGJMP";
|
||||
case SPISD::Hi: return "SPISD::Hi";
|
||||
case SPISD::Lo: return "SPISD::Lo";
|
||||
case SPISD::FTOI: return "SPISD::FTOI";
|
||||
@ -2502,20 +2497,6 @@ static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
|
||||
DAG.getConstant(SPCC, dl, MVT::i32), CompareFlag);
|
||||
}
|
||||
|
||||
SDValue SparcTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG,
|
||||
const SparcTargetLowering &TLI) const {
|
||||
SDLoc DL(Op);
|
||||
return DAG.getNode(SPISD::EH_SJLJ_SETJMP, DL,
|
||||
DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0), Op.getOperand(1));
|
||||
|
||||
}
|
||||
|
||||
SDValue SparcTargetLowering::LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG,
|
||||
const SparcTargetLowering &TLI) const {
|
||||
SDLoc DL(Op);
|
||||
return DAG.getNode(SPISD::EH_SJLJ_LONGJMP, DL, MVT::Other, Op.getOperand(0), Op.getOperand(1));
|
||||
}
|
||||
|
||||
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG,
|
||||
const SparcTargetLowering &TLI) {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
@ -3045,8 +3026,6 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||
hasHardQuad);
|
||||
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, *this,
|
||||
hasHardQuad);
|
||||
case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG, *this);
|
||||
case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG, *this);
|
||||
case ISD::VASTART: return LowerVASTART(Op, DAG, *this);
|
||||
case ISD::VAARG: return LowerVAARG(Op, DAG);
|
||||
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG,
|
||||
@ -3129,13 +3108,6 @@ SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
|
||||
case SP::SELECT_CC_DFP_FCC:
|
||||
case SP::SELECT_CC_QFP_FCC:
|
||||
return expandSelectCC(MI, BB, SP::FBCOND);
|
||||
case SP::EH_SJLJ_SETJMP32ri:
|
||||
case SP::EH_SJLJ_SETJMP32rr:
|
||||
return emitEHSjLjSetJmp(MI, BB);
|
||||
case SP::EH_SJLJ_LONGJMP32rr:
|
||||
case SP::EH_SJLJ_LONGJMP32ri:
|
||||
return emitEHSjLjLongJmp(MI, BB);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -3195,205 +3167,6 @@ SparcTargetLowering::expandSelectCC(MachineInstr &MI, MachineBasicBlock *BB,
|
||||
return SinkMBB;
|
||||
}
|
||||
|
||||
MachineBasicBlock *
|
||||
SparcTargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
|
||||
MachineBasicBlock *MBB) const {
|
||||
DebugLoc DL = MI.getDebugLoc();
|
||||
const TargetInstrInfo *TII = Subtarget->getInstrInfo();
|
||||
|
||||
MachineFunction *MF = MBB->getParent();
|
||||
MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||
MachineInstrBuilder MIB;
|
||||
|
||||
MVT PVT = getPointerTy(MF->getDataLayout());
|
||||
unsigned RegSize = PVT.getStoreSize();
|
||||
assert(PVT == MVT::i32 && "Invalid Pointer Size!");
|
||||
|
||||
unsigned Buf = MI.getOperand(0).getReg();
|
||||
unsigned JmpLoc = MRI.createVirtualRegister(&SP::IntRegsRegClass);
|
||||
|
||||
// TO DO: If we do 64-bit handling, this perhaps should be FLUSHW, not TA 3
|
||||
MIB = BuildMI(*MBB, MI, DL, TII->get(SP::TRAPri), SP::G0).addImm(3).addImm(SPCC::ICC_A);
|
||||
|
||||
// Instruction to restore FP
|
||||
const unsigned FP = SP::I6;
|
||||
MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))
|
||||
.addReg(FP)
|
||||
.addReg(Buf)
|
||||
.addImm(0);
|
||||
|
||||
// Instruction to load jmp location
|
||||
MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))
|
||||
.addReg(JmpLoc, RegState::Define)
|
||||
.addReg(Buf)
|
||||
.addImm(RegSize);
|
||||
|
||||
// Instruction to restore SP
|
||||
const unsigned SP = SP::O6;
|
||||
MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))
|
||||
.addReg(SP)
|
||||
.addReg(Buf)
|
||||
.addImm(2 * RegSize);
|
||||
|
||||
// Instruction to restore I7
|
||||
MIB = BuildMI(*MBB, MI, DL, TII->get(SP::LDri))
|
||||
.addReg(SP::I7)
|
||||
.addReg(Buf, RegState::Kill)
|
||||
.addImm(3 * RegSize);
|
||||
|
||||
// Jump to JmpLoc
|
||||
BuildMI(*MBB, MI, DL, TII->get(SP::JMPLrr)).addReg(SP::G0).addReg(JmpLoc, RegState::Kill).addReg(SP::G0);
|
||||
|
||||
MI.eraseFromParent();
|
||||
return MBB;
|
||||
}
|
||||
|
||||
MachineBasicBlock *
|
||||
SparcTargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
|
||||
MachineBasicBlock *MBB) const {
|
||||
DebugLoc DL = MI.getDebugLoc();
|
||||
const TargetInstrInfo *TII = Subtarget->getInstrInfo();
|
||||
const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
|
||||
|
||||
MachineFunction *MF = MBB->getParent();
|
||||
MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||
MachineInstrBuilder MIB;
|
||||
|
||||
MVT PVT = getPointerTy(MF->getDataLayout());
|
||||
unsigned RegSize = PVT.getStoreSize();
|
||||
assert(PVT == MVT::i32 && "Invalid Pointer Size!");
|
||||
|
||||
unsigned DstReg = MI.getOperand(0).getReg();
|
||||
const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
|
||||
assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!");
|
||||
(void)TRI;
|
||||
unsigned mainDstReg = MRI.createVirtualRegister(RC);
|
||||
unsigned restoreDstReg = MRI.createVirtualRegister(RC);
|
||||
|
||||
// For v = setjmp(buf), we generate
|
||||
//
|
||||
// thisMBB:
|
||||
// buf[0] = FP
|
||||
// buf[RegSize] = restoreMBB <-- takes address of restoreMBB
|
||||
// buf[RegSize * 2] = O6
|
||||
// buf[RegSize * 3] = I7
|
||||
// Ensure restoreMBB remains in the relocations list (done using a bn instruction)
|
||||
// b mainMBB
|
||||
//
|
||||
// mainMBB:
|
||||
// v_main = 0
|
||||
// b sinkMBB
|
||||
//
|
||||
// restoreMBB:
|
||||
// v_restore = 1
|
||||
// --fall through--
|
||||
//
|
||||
// sinkMBB:
|
||||
// v = phi(main, restore)
|
||||
|
||||
const BasicBlock *BB = MBB->getBasicBlock();
|
||||
MachineFunction::iterator It = ++MBB->getIterator();
|
||||
MachineBasicBlock *thisMBB = MBB;
|
||||
MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(BB);
|
||||
MachineBasicBlock *restoreMBB = MF->CreateMachineBasicBlock(BB);
|
||||
MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB);
|
||||
|
||||
MF->insert(It, mainMBB);
|
||||
MF->insert(It, restoreMBB);
|
||||
MF->insert(It, sinkMBB);
|
||||
restoreMBB->setHasAddressTaken();
|
||||
|
||||
// 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);
|
||||
|
||||
unsigned LabelReg = MRI.createVirtualRegister(&SP::IntRegsRegClass);
|
||||
unsigned LabelReg2 = MRI.createVirtualRegister(&SP::IntRegsRegClass);
|
||||
unsigned BufReg = MI.getOperand(1).getReg();
|
||||
|
||||
// Instruction to store FP
|
||||
const unsigned FP = SP::I6;
|
||||
MIB = BuildMI(thisMBB, DL, TII->get(SP::STri))
|
||||
.addReg(BufReg)
|
||||
.addImm(0)
|
||||
.addReg(FP);
|
||||
|
||||
// Instructions to store jmp location
|
||||
MIB = BuildMI(thisMBB, DL, TII->get(SP::SETHIi))
|
||||
.addReg(LabelReg, RegState::Define)
|
||||
.addMBB(restoreMBB, SparcMCExpr::VK_Sparc_HI);
|
||||
|
||||
MIB = BuildMI(thisMBB, DL, TII->get(SP::ORri))
|
||||
.addReg(LabelReg2, RegState::Define)
|
||||
.addReg(LabelReg, RegState::Kill)
|
||||
.addMBB(restoreMBB, SparcMCExpr::VK_Sparc_LO);
|
||||
|
||||
MIB = BuildMI(thisMBB, DL, TII->get(SP::STri))
|
||||
.addReg(BufReg)
|
||||
.addImm(RegSize)
|
||||
.addReg(LabelReg2, RegState::Kill);
|
||||
|
||||
// Instruction to store SP
|
||||
const unsigned SP = SP::O6;
|
||||
MIB = BuildMI(thisMBB, DL, TII->get(SP::STri))
|
||||
.addReg(BufReg)
|
||||
.addImm(2 * RegSize)
|
||||
.addReg(SP);
|
||||
|
||||
// Instruction to store I7
|
||||
MIB = BuildMI(thisMBB, DL, TII->get(SP::STri))
|
||||
.addReg(BufReg)
|
||||
.addImm(3 * RegSize)
|
||||
.addReg(SP::I7);
|
||||
|
||||
|
||||
// FIX ME: This next instruction ensures that the restoreMBB block address remains
|
||||
// valid through optimization passes and serves no other purpose. The ICC_N ensures
|
||||
// that the branch is never taken. This commented-out code here was an alternative
|
||||
// attempt to achieve this which brought myriad problems.
|
||||
//MIB = BuildMI(thisMBB, DL, TII->get(SP::EH_SjLj_Setup)).addMBB(restoreMBB, SparcMCExpr::VK_Sparc_None);
|
||||
MIB = BuildMI(thisMBB, DL, TII->get(SP::BCOND))
|
||||
.addMBB(restoreMBB)
|
||||
.addImm(SPCC::ICC_N);
|
||||
|
||||
MIB = BuildMI(thisMBB, DL, TII->get(SP::BCOND))
|
||||
.addMBB(mainMBB)
|
||||
.addImm(SPCC::ICC_A);
|
||||
|
||||
thisMBB->addSuccessor(mainMBB);
|
||||
thisMBB->addSuccessor(restoreMBB);
|
||||
|
||||
|
||||
// mainMBB:
|
||||
MIB = BuildMI(mainMBB, DL, TII->get(SP::ORrr))
|
||||
.addReg(mainDstReg, RegState::Define)
|
||||
.addReg(SP::G0)
|
||||
.addReg(SP::G0);
|
||||
MIB = BuildMI(mainMBB, DL, TII->get(SP::BCOND)).addMBB(sinkMBB).addImm(SPCC::ICC_A);
|
||||
|
||||
mainMBB->addSuccessor(sinkMBB);
|
||||
|
||||
|
||||
// restoreMBB:
|
||||
MIB = BuildMI(restoreMBB, DL, TII->get(SP::ORri))
|
||||
.addReg(restoreDstReg, RegState::Define)
|
||||
.addReg(SP::G0)
|
||||
.addImm(1);
|
||||
//MIB = BuildMI(restoreMBB, DL, TII->get(SP::BCOND)).addMBB(sinkMBB).addImm(SPCC::ICC_A);
|
||||
restoreMBB->addSuccessor(sinkMBB);
|
||||
|
||||
// sinkMBB:
|
||||
MIB = BuildMI(*sinkMBB, sinkMBB->begin(), DL,
|
||||
TII->get(SP::PHI), DstReg)
|
||||
.addReg(mainDstReg).addMBB(mainMBB)
|
||||
.addReg(restoreDstReg).addMBB(restoreMBB);
|
||||
|
||||
MI.eraseFromParent();
|
||||
return sinkMBB;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Sparc Inline Assembly Support
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -33,9 +33,6 @@ namespace llvm {
|
||||
SELECT_XCC, // Select between two values using the current XCC flags.
|
||||
SELECT_FCC, // Select between two values using the current FCC flags.
|
||||
|
||||
EH_SJLJ_SETJMP, // builtin setjmp operation
|
||||
EH_SJLJ_LONGJMP, // builtin longjmp operation
|
||||
|
||||
Hi, Lo, // Hi/Lo operations, typically on a global address.
|
||||
|
||||
FTOI, // FP to Int within a FP register.
|
||||
@ -171,11 +168,6 @@ namespace llvm {
|
||||
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG,
|
||||
const SparcTargetLowering &TLI) const ;
|
||||
SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG,
|
||||
const SparcTargetLowering &TLI) const ;
|
||||
|
||||
SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const;
|
||||
SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
|
||||
SelectionDAG &DAG) const;
|
||||
@ -219,10 +211,6 @@ namespace llvm {
|
||||
|
||||
MachineBasicBlock *expandSelectCC(MachineInstr &MI, MachineBasicBlock *BB,
|
||||
unsigned BROpcode) const;
|
||||
MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
|
||||
MachineBasicBlock *MBB) const;
|
||||
MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,
|
||||
MachineBasicBlock *MBB) const;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -186,9 +186,6 @@ SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>;
|
||||
def SDTSPtlsld :
|
||||
SDTypeProfile<1, 2, [SDTCisPtrTy<0>, SDTCisPtrTy<1>]>;
|
||||
|
||||
def SDTSPeh_sjlj_setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
|
||||
def SDTSPeh_sjlj_longjmp: SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
|
||||
|
||||
def SPcmpicc : SDNode<"SPISD::CMPICC", SDTSPcmpicc, [SDNPOutGlue]>;
|
||||
def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>;
|
||||
def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
|
||||
@ -207,13 +204,6 @@ def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInGlue]>;
|
||||
def SPselectxcc : SDNode<"SPISD::SELECT_XCC", SDTSPselectcc, [SDNPInGlue]>;
|
||||
def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInGlue]>;
|
||||
|
||||
def SPsjlj_setjmp: SDNode<"SPISD::EH_SJLJ_SETJMP",
|
||||
SDTSPeh_sjlj_setjmp,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
def SPsjlj_longjmp: SDNode<"SPISD::EH_SJLJ_LONGJMP",
|
||||
SDTSPeh_sjlj_longjmp,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
// These are target-independent nodes, but have target-specific formats.
|
||||
def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,
|
||||
SDTCisVT<1, i32> ]>;
|
||||
@ -490,27 +480,6 @@ let usesCustomInserter = 1, Uses = [FCC0] in {
|
||||
[(set f128:$dst, (SPselectfcc f128:$T, f128:$F, imm:$Cond))]>;
|
||||
}
|
||||
|
||||
let hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
|
||||
let Defs = [WIM] in
|
||||
def EH_SJLJ_SETJMP32ri : Pseudo<(outs IntRegs:$dst), (ins MEMri:$buf),
|
||||
"#EH_SJLJ_SETJMP32",
|
||||
[(set i32:$dst, (SPsjlj_setjmp ADDRri:$buf))]>,
|
||||
Requires<[Is32Bit]>;
|
||||
def EH_SJLJ_SETJMP32rr : Pseudo<(outs IntRegs:$dst), (ins MEMrr:$buf),
|
||||
"#EH_SJLJ_SETJMP32",
|
||||
[(set i32:$dst, (SPsjlj_setjmp ADDRrr:$buf))]>,
|
||||
Requires<[Is32Bit]>;
|
||||
let isTerminator = 1 in
|
||||
def EH_SJLJ_LONGJMP32ri : Pseudo<(outs), (ins MEMri:$buf),
|
||||
"#EH_SJLJ_LONGJMP32",
|
||||
[(SPsjlj_longjmp ADDRri:$buf)]>,
|
||||
Requires<[Is32Bit]>;
|
||||
def EH_SJLJ_LONGJMP32rr : Pseudo<(outs), (ins MEMrr:$buf),
|
||||
"#EH_SJLJ_LONGJMP32",
|
||||
[(SPsjlj_longjmp ADDRrr:$buf)]>,
|
||||
Requires<[Is32Bit]>;
|
||||
}
|
||||
|
||||
// Section B.1 - Load Integer Instructions, p. 90
|
||||
let DecoderMethod = "DecodeLoadInt" in {
|
||||
defm LDSB : LoadA<"ldsb", 0b001001, 0b011001, sextloadi8, IntRegs, i32>;
|
||||
|
@ -1,93 +0,0 @@
|
||||
; RUN: llc < %s -march=sparc | FileCheck %s
|
||||
; RUN: llc < %s -march=sparc -mcpu=leon2 | FileCheck %s
|
||||
; RUN: llc < %s -march=sparc -mcpu=leon3 | FileCheck %s
|
||||
; RUN: llc < %s -march=sparc -mcpu=leon4 | FileCheck %s
|
||||
|
||||
%struct.__jmp_buf_tag = type { [64 x i64], i32, %struct.__sigset_t, [8 x i8] }
|
||||
%struct.__sigset_t = type { [16 x i64] }
|
||||
|
||||
@env_sigill = internal global [1 x %struct.__jmp_buf_tag] zeroinitializer, align 16
|
||||
|
||||
define void @foo() #0 {
|
||||
entry:
|
||||
call void @llvm.eh.sjlj.longjmp(i8* bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8*))
|
||||
unreachable
|
||||
|
||||
; CHECK: @foo
|
||||
; CHECK: ta 3
|
||||
; CHECK: ld [%i0], %fp
|
||||
; CHECK: ld [%i0+4], %i1
|
||||
; CHECK: ld [%i0+8], %sp
|
||||
; CHECK: jmp %i1
|
||||
; CHECK: ld [%i0+12], %i7
|
||||
|
||||
return: ; No predecessors!
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.eh.sjlj.longjmp(i8*) #1
|
||||
|
||||
define signext i32 @main() #0 {
|
||||
entry:
|
||||
%retval = alloca i32, align 4
|
||||
store i32 0, i32* %retval
|
||||
%0 = call i8* @llvm.frameaddress(i32 0)
|
||||
store i8* %0, i8** bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8**)
|
||||
%1 = call i8* @llvm.stacksave()
|
||||
store i8* %1, i8** getelementptr (i8*, i8** bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8**), i32 2)
|
||||
%2 = call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8*))
|
||||
%tobool = icmp ne i32 %2, 0
|
||||
br i1 %tobool, label %if.then, label %if.else
|
||||
|
||||
if.then: ; preds = %entry
|
||||
store i32 1, i32* %retval
|
||||
br label %return
|
||||
|
||||
if.else: ; preds = %entry
|
||||
call void @foo()
|
||||
br label %if.end
|
||||
|
||||
if.end: ; preds = %if.else
|
||||
store i32 0, i32* %retval
|
||||
br label %return
|
||||
|
||||
return: ; preds = %if.end, %if.then
|
||||
%3 = load i32, i32* %retval
|
||||
ret i32 %3
|
||||
|
||||
; CHECK: @main
|
||||
; CHECK: st %fp, [%i0]
|
||||
; CHECK: sethi %hi(.LBB1_2), %i1
|
||||
; CHECK: or %i1, %lo(.LBB1_2), %i1
|
||||
; CHECK: st %i1, [%i0+4]
|
||||
; CHECK: st %sp, [%i0+8]
|
||||
; CHECK: bn .LBB1_2
|
||||
; CHECK: st %i7, [%i0+12]
|
||||
; CHECK: ba .LBB1_1
|
||||
; CHECK: nop
|
||||
; CHECK:.LBB1_1: ! %entry
|
||||
; CHECK: mov %g0, %i0
|
||||
; CHECK: ! %entry
|
||||
; CHECK: cmp %i0, 0
|
||||
; CHECK: be .LBB1_5
|
||||
; CHECK: nop
|
||||
; CHECK:.LBB1_4:
|
||||
; CHECK: mov 1, %i0
|
||||
; CHECK: ba .LBB1_6
|
||||
; CHECK:.LBB1_2: ! Block address taken
|
||||
; CHECK: mov 1, %i0
|
||||
; CHECK: cmp %i0, 0
|
||||
; CHECK: bne .LBB1_4
|
||||
; CHECK: nop
|
||||
}
|
||||
declare i8* @llvm.frameaddress(i32) #2
|
||||
|
||||
declare i8* @llvm.stacksave() #3
|
||||
|
||||
declare i32 @llvm.eh.sjlj.setjmp(i8*) #3
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { noreturn nounwind }
|
||||
attributes #2 = { nounwind readnone }
|
||||
attributes #3 = { nounwind }
|
||||
|
Loading…
Reference in New Issue
Block a user