[GlobalISel] Add ISel support for @llvm.lifetime.start and @llvm.lifetime.end

This adds ISel support for lifetime markers in opt levels above O0.

It also updates the arm64-irtranslator test, and updates some AArch64 tests that
use them for added coverage.

It also adds a testcase taken from the X86 codegen tests which verified a bug
caused by lifetime markers + stack colouring in the past. This is intended to
make sure that GISel doesn't re-introduce the bug.

(This is basically a straight copy from what SelectionDAG does in
SelectionDAGBuilder.cpp)

https://reviews.llvm.org/D57187

llvm-svn: 352410
This commit is contained in:
Jessica Paquette 2019-01-28 19:22:29 +00:00
parent a3185934da
commit 66fe35406b
5 changed files with 95 additions and 6 deletions

View File

@ -16,6 +16,7 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
@ -793,13 +794,33 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
default:
break;
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
// Stack coloring is not enabled in O0 (which we care about now) so we can
// drop these. Make sure someone notices when we start compiling at higher
// opts though.
if (MF->getTarget().getOptLevel() != CodeGenOpt::None)
return false;
case Intrinsic::lifetime_end: {
// No stack colouring in O0, discard region information.
if (MF->getTarget().getOptLevel() == CodeGenOpt::None)
return true;
unsigned Op = ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
: TargetOpcode::LIFETIME_END;
// Get the underlying objects for the location passed on the lifetime
// marker.
SmallVector<Value *, 4> Allocas;
GetUnderlyingObjects(CI.getArgOperand(1), Allocas, *DL);
// Iterate over each underlying object, creating lifetime markers for each
// static alloca. Quit if we find a non-static alloca.
for (Value *V : Allocas) {
AllocaInst *AI = dyn_cast<AllocaInst>(V);
if (!AI)
continue;
if (!AI->isStaticAlloca())
return true;
MIRBuilder.buildInstr(Op).addFrameIndex(getOrCreateFrameIndex(*AI));
}
return true;
}
case Intrinsic::dbg_declare: {
const DbgDeclareInst &DI = cast<DbgDeclareInst>(CI);
assert(DI.getVariable() && "Missing variable");

View File

@ -1,4 +1,5 @@
; RUN: llc -O0 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
; RUN: llc -O3 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefix=O3
; This file checks that the translation from llvm IR to generic MachineInstr
; is correct.
@ -1481,6 +1482,11 @@ declare void @llvm.lifetime.end.p0i8(i64, i8*)
define void @test_lifetime_intrin() {
; CHECK-LABEL: name: test_lifetime_intrin
; CHECK: RET_ReallyLR
; O3-LABEL: name: test_lifetime_intrin
; O3: {{%[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.slot
; O3-NEXT: LIFETIME_START %stack.0.slot
; O3-NEXT: LIFETIME_END %stack.0.slot
; O3-NEXT: RET_ReallyLR
%slot = alloca i8, i32 4
call void @llvm.lifetime.start.p0i8(i64 0, i8* %slot)
call void @llvm.lifetime.end.p0i8(i64 0, i8* %slot)

View File

@ -0,0 +1,47 @@
; RUN: llc -mtriple aarch64-unknown-unknown -global-isel \
; RUN: -no-stack-coloring=false -pass-remarks-missed=gisel* < %s \
; RUN: 2>&1 | FileCheck %s
; Same as the dynamic-alloca-lifetime.ll X86 test, which was used to fix a bug
; in stack colouring + lifetime markers.
; This test crashed in PEI because the stack protector was dead.
; This was due to it being colored, which was in turn due to incorrect
; lifetimes being applied to the stack protector frame index.
; CHECK: stack_chk_guard
; CHECK-NOT: remark{{.*}}foo
; Function Attrs: nounwind
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #0
; Function Attrs: nounwind
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #0
; Function Attrs: ssp
define void @foo(i1 %cond1, i1 %cond2) #1 {
entry:
%bitmapBuffer = alloca [8192 x i8], align 1
br i1 %cond1, label %end1, label %bb1
bb1:
%bitmapBuffer229 = alloca [8192 x i8], align 1
br i1 %cond2, label %end1, label %if.else130
end1:
ret void
if.else130: ; preds = %bb1
%tmp = getelementptr inbounds [8192 x i8], [8192 x i8]* %bitmapBuffer, i32 0, i32 0
call void @llvm.lifetime.start.p0i8(i64 8192, i8* %tmp) #0
call void @llvm.lifetime.end.p0i8(i64 8192, i8* %tmp) #0
%tmp25 = getelementptr inbounds [8192 x i8], [8192 x i8]* %bitmapBuffer229, i32 0, i32 0
call void @llvm.lifetime.start.p0i8(i64 8192, i8* %tmp25) #0
call void @llvm.lifetime.end.p0i8(i64 8192, i8* %tmp25) #0
br label %end1
}
declare void @bar()
attributes #0 = { nounwind }
attributes #1 = { ssp }

View File

@ -1,4 +1,6 @@
; RUN: llc < %s -mtriple=aarch64-w64-mingw32 | FileCheck %s
; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* \
; RUN: -mtriple=aarch64-w64-mingw32 2>&1| FileCheck %s --check-prefixes=GISEL,FALLBACK
@var = external local_unnamed_addr global i32, align 4
@dsolocalvar = external dso_local local_unnamed_addr global i32, align 4
@ -68,11 +70,16 @@ entry:
declare dso_local void @otherFunc()
; FALLBACK-NOT: remark:{{.*}}sspFunc
define dso_local void @sspFunc() #0 {
; CHECK-LABEL: sspFunc:
; CHECK: adrp x8, .refptr.__stack_chk_guard
; CHECK: ldr x8, [x8, .refptr.__stack_chk_guard]
; CHECK: ldr x8, [x8]
; GISEL-LABEL: sspFunc:
; GISEL: adrp x8, .refptr.__stack_chk_guard
; GISEL: ldr x8, [x8, .refptr.__stack_chk_guard]
; GISEL: ldr x8, [x8]
entry:
%c = alloca i8, align 1
call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %c)

View File

@ -4,6 +4,12 @@
; RUN: llc < %s -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=large -no-integrated-as | FileCheck %s -check-prefix=STATIC-LARGE
; RUN: llc < %s -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=small -no-integrated-as | FileCheck %s -check-prefix=STATIC-SMALL
; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=arm64-apple-ios -relocation-model=pic -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=DARWIN,FALLBACK
; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=arm64-apple-ios -relocation-model=static -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=DARWIN,FALLBACK
; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-linux-gnu -relocation-model=pic -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=PIC-LINUX,FALLBACK
; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=large -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=STATIC-LARGE,FALLBACK
; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=small -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=STATIC-SMALL,FALLBACK
; DARWIN: foo2
; DARWIN: adrp [[R0:x[0-9]+]], ___stack_chk_guard@GOTPAGE
; DARWIN: ldr [[R1:x[0-9]+]], {{\[}}[[R0]], ___stack_chk_guard@GOTPAGEOFF{{\]}}
@ -25,6 +31,8 @@
; STATIC-SMALL: adrp [[R0:x[0-9]+]], __stack_chk_guard
; STATIC-SMALL: ldr {{x[0-9]+}}, {{\[}}[[R0]], :lo12:__stack_chk_guard{{\]}}
; FALLBACK-NOT: remark:{{.*}}llvm.lifetime.end
; FALLBACK-NOT: remark:{{.*}}llvm.lifetime.start
define i32 @test_stack_guard_remat() #0 {
entry:
%a1 = alloca [256 x i32], align 4