Index: lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- lib/CodeGen/GlobalISel/IRTranslator.cpp +++ lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -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 @@ 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 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_or_null(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(CI); assert(DI.getVariable() && "Missing variable"); Index: test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll =================================================================== --- test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -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. @@ -1471,6 +1472,11 @@ 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) Index: test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll @@ -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 } Index: test/CodeGen/AArch64/mingw-refptr.ll =================================================================== --- test/CodeGen/AArch64/mingw-refptr.ll +++ test/CodeGen/AArch64/mingw-refptr.ll @@ -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 @@ 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) Index: test/CodeGen/AArch64/stack_guard_remat.ll =================================================================== --- test/CodeGen/AArch64/stack_guard_remat.ll +++ test/CodeGen/AArch64/stack_guard_remat.ll @@ -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