Skip to content

Commit

Permalink
[GISel] Check useLoadStackGuardNode() before generating LOAD_STACK_GUARD
Browse files Browse the repository at this point in the history
When lowering llvm::stackprotect intrinsic, the SDAG implementation
checks useLoadStackGuardNode() to either create a LOAD_STACK_GUARD or use
the first argument of the intrinsic. This check is not present in the
IRTranslator, which results in always generating a LOAD_STACK_GUARD even
if the target does not support it.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D129505
  • Loading branch information
redstar committed Jul 12, 2022
1 parent a280043 commit 42f7364
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
9 changes: 7 additions & 2 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Expand Up @@ -2076,9 +2076,14 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
getStackGuard(getOrCreateVReg(CI), MIRBuilder);
return true;
case Intrinsic::stackprotector: {
const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL);
Register GuardVal = MRI->createGenericVirtualRegister(PtrTy);
getStackGuard(GuardVal, MIRBuilder);
Register GuardVal;
if (TLI.useLoadStackGuardNode()) {
GuardVal = MRI->createGenericVirtualRegister(PtrTy);
getStackGuard(GuardVal, MIRBuilder);
} else
GuardVal = getOrCreateVReg(*CI.getArgOperand(0)); // The guard's value.

AllocaInst *Slot = cast<AllocaInst>(CI.getArgOperand(1));
int FI = getOrCreateFrameIndex(*Slot);
Expand Down
@@ -0,0 +1,49 @@
; RUN: llc -verify-machineinstrs -mtriple=ppc64le-unknown-linux %s -global-isel -stop-after=irtranslator -o - | FileCheck %s --check-prefix=LINUX
; RUN: llc -verify-machineinstrs -mtriple=ppc64le-unknown-openbsd %s -global-isel -stop-after=irtranslator -o - | FileCheck %s --check-prefix=OPENBSD


; The stack guard on Linux
@__stack_chk_guard = external global ptr

; The stack guard on OpenBSD
@__guard_local = external hidden global ptr

declare void @llvm.stackprotector(ptr, ptr)

; LINUX-LABEL: name: test_stack_guard_linux

; LINUX: frameInfo:
; LINUX: stackProtector: '%stack.0.StackGuardSlot'

; LINUX: stack:
; LINUX: - { id: 0, name: StackGuardSlot, type: default, offset: 0, size: 8, alignment: 8,
; LINUX-NOT: id: 1

; LINUX: [[GUARD_SLOT:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.StackGuardSlot
; LINUX: [[GUARD:%[0-9]+]]:g8rc(p0) = LOAD_STACK_GUARD :: (dereferenceable invariant load (p0) from @__stack_chk_guard)
; LINUX: G_STORE [[GUARD]](p0), [[GUARD_SLOT]](p0) :: (volatile store (p0) into %stack.0.StackGuardSlot)
define void @test_stack_guard_linux() {
%StackGuardSlot = alloca ptr
call void @llvm.stackprotector(ptr undef, ptr %StackGuardSlot)
ret void
}

; OPENBSD-LABEL: name: test_stack_guard_openbsd

; OPENBSD: frameInfo:
; OPENBSD: stackProtector: '%stack.0.StackGuardSlot'

; OPENBSD: stack:
; OPENBSD: - { id: 0, name: StackGuardSlot, type: default, offset: 0, size: 8, alignment: 8,
; OPENBSD-NOT: id: 1

; OPENBSD: [[GUARD_LOCAL:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @__guard_local
; OPENBSD: [[GUARD_SLOT:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.StackGuardSlot
; OPENBSD: [[GUARD:%[0-9]+]]:_(p0) = G_LOAD [[GUARD_LOCAL]](p0) :: (dereferenceable load (p0) from @__guard_local)
; OPENBSD: G_STORE [[GUARD]](p0), [[GUARD_SLOT]](p0) :: (volatile store (p0) into %stack.0.StackGuardSlot)
define void @test_stack_guard_openbsd() {
%StackGuardSlot = alloca i8*
%StackGuard = load ptr, ptr @__guard_local
call void @llvm.stackprotector(ptr %StackGuard, ptr %StackGuardSlot)
ret void
}

0 comments on commit 42f7364

Please sign in to comment.