diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index cc6eac70ba7..c88aad66934 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1814,12 +1814,14 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD, SDValue Guard; - // If useLoadStackGuardNode returns true, retrieve the guard value from - // the virtual register holding the value. Otherwise, emit a volatile load - // to retrieve the stack guard value. - if (TLI->useLoadStackGuardNode()) - Guard = DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), - SPD.getGuardReg(), PtrTy); + // If GuardReg is set and useLoadStackGuardNode returns true, retrieve the + // guard value from the virtual register holding the value. Otherwise, emit a + // volatile load to retrieve the stack guard value. + unsigned GuardReg = SPD.getGuardReg(); + + if (GuardReg && TLI->useLoadStackGuardNode()) + Guard = DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), GuardReg, + PtrTy); else Guard = DAG.getLoad(PtrTy, getCurSDLoc(), DAG.getEntryNode(), GuardPtr, MachinePointerInfo(IRGuard, 0), @@ -5263,13 +5265,21 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { MachineFrameInfo *MFI = MF.getFrameInfo(); EVT PtrTy = TLI->getPointerTy(); SDValue Src, Chain = getRoot(); + const Value *Ptr = cast<LoadInst>(I.getArgOperand(0))->getPointerOperand(); + const GlobalVariable *GV = dyn_cast<GlobalVariable>(Ptr); - if (TLI->useLoadStackGuardNode()) { + // See if Ptr is a bitcast. If it is, look through it and see if we can get + // global variable __stack_chk_guard. + if (!GV) + if (const Operator *BC = dyn_cast<Operator>(Ptr)) + if (BC->getOpcode() == Instruction::BitCast) + GV = dyn_cast<GlobalVariable>(BC->getOperand(0)); + + if (GV && TLI->useLoadStackGuardNode()) { // Emit a LOAD_STACK_GUARD node. MachineSDNode *Node = DAG.getMachineNode(TargetOpcode::LOAD_STACK_GUARD, sdl, PtrTy, Chain); - LoadInst *LI = cast<LoadInst>(I.getArgOperand(0)); - MachinePointerInfo MPInfo(LI->getPointerOperand()); + MachinePointerInfo MPInfo(GV); MachineInstr::mmo_iterator MemRefs = MF.allocateMemRefsArray(1); unsigned Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant; diff --git a/test/CodeGen/AArch64/stack-guard-remat-bitcast.ll b/test/CodeGen/AArch64/stack-guard-remat-bitcast.ll new file mode 100644 index 00000000000..bedbf5facbb --- /dev/null +++ b/test/CodeGen/AArch64/stack-guard-remat-bitcast.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -mtriple=arm64-apple-ios -relocation-model=pic | FileCheck %s + +@__stack_chk_guard = external global i64* + +; PR20558 + +; CHECK: adrp [[R0:x[0-9]+]], ___stack_chk_guard@GOTPAGE +; CHECK: ldr [[R1:x[0-9]+]], {{\[}}[[R0]], ___stack_chk_guard@GOTPAGEOFF{{\]}} +; CHECK: ldr [[R2:x[0-9]+]], {{\[}}[[R1]]{{\]}} +; CHECK: stur [[R2]], {{\[}}x29, [[SLOT0:[0-9#\-]+]]{{\]}} +; CHECK: ldur [[R3:x[0-9]+]], {{\[}}x29, [[SLOT0]]{{\]}} +; CHECK: sub [[R4:x[0-9]+]], [[R2]], [[R3]] +; CHECK: cbnz [[R4]], LBB + +define i32 @test_stack_guard_remat2() { +entry: + %StackGuardSlot = alloca i8* + %StackGuard = load i8** bitcast (i64** @__stack_chk_guard to i8**) + call void @llvm.stackprotector(i8* %StackGuard, i8** %StackGuardSlot) + %container = alloca [32 x i8], align 1 + call void @llvm.stackprotectorcheck(i8** bitcast (i64** @__stack_chk_guard to i8**)) + ret i32 -1 +} + +declare void @llvm.stackprotector(i8*, i8**) +declare void @llvm.stackprotectorcheck(i8**)