diff options
-rw-r--r-- | llvm/lib/CodeGen/StackProtector.cpp | 15 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/stack-protector-dbginfo.ll | 18 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/stack-protector.ll | 17 |
3 files changed, 48 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp index 62cef95a4af..8a7393501d0 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -36,6 +36,7 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" @@ -182,6 +183,14 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool &IsLarge, return NeedsProtector; } +static bool isLifetimeInst(const Instruction *I) { + if (const auto Intrinsic = dyn_cast<IntrinsicInst>(I)) { + const auto Id = Intrinsic->getIntrinsicID(); + return Id == Intrinsic::lifetime_start || Id == Intrinsic::lifetime_end; + } + return false; +} + bool StackProtector::HasAddressTaken(const Instruction *AI) { for (const User *U : AI->users()) { if (const StoreInst *SI = dyn_cast<StoreInst>(U)) { @@ -190,8 +199,10 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) { } else if (const PtrToIntInst *SI = dyn_cast<PtrToIntInst>(U)) { if (AI == SI->getOperand(0)) return true; - } else if (isa<CallInst>(U)) { - return true; + } else if (const CallInst *CI = dyn_cast<CallInst>(U)) { + // Ignore intrinsics that are not calls. TODO: Use isLoweredToCall(). + if (!isa<DbgInfoIntrinsic>(CI) && !isLifetimeInst(CI)) + return true; } else if (isa<InvokeInst>(U)) { return true; } else if (const SelectInst *SI = dyn_cast<SelectInst>(U)) { diff --git a/llvm/test/CodeGen/X86/stack-protector-dbginfo.ll b/llvm/test/CodeGen/X86/stack-protector-dbginfo.ll index a685ed1f678..3cdcefb4503 100644 --- a/llvm/test/CodeGen/X86/stack-protector-dbginfo.ll +++ b/llvm/test/CodeGen/X86/stack-protector-dbginfo.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - +; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=IGNORE_INTRIN %s ; PR16954 ; @@ -17,8 +18,22 @@ entry: ret i32 %1 } +define i32 @IgnoreIntrinsicTest() #1 { +; IGNORE_INTRIN: IgnoreIntrinsicTest: + %1 = alloca i32, align 4 + %2 = bitcast i32* %1 to i8* + call void @llvm.dbg.declare(metadata i32* %1, metadata !73, metadata !DIExpression()), !dbg !74 + store volatile i32 1, i32* %1, align 4 + %3 = load volatile i32, i32* %1, align 4 + %4 = mul nsw i32 %3, 42 + ret i32 %4 +; IGNORE_INTRIN-NOT: callq __stack_chk_fail +; IGNORE_INTRIN: .cfi_endproc +} + ; Function Attrs: nounwind readnone declare void @llvm.dbg.value(metadata, i64, metadata, metadata) +declare void @llvm.dbg.declare(metadata, metadata, metadata) attributes #0 = { sspreq } @@ -93,3 +108,6 @@ attributes #0 = { sspreq } !70 = !DILocalVariable(name: "", line: 2, arg: 3, scope: !65, file: !10, type: !50) !71 = !DILocation(line: 1, scope: !65, inlinedAt: !40) !72 = !{i32 1, !"Debug Info Version", i32 3} +!73 = !DILocalVariable(name: "x", scope: !74, file: !1, line: 2, type: !13) +!74 = distinct !DISubprogram(name: "IgnoreIntrinsicTest", linkageName: "IgnoreIntrinsicTest", scope: !1, file: !1, line: 1, type: !13, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !5) +!75 = !DILocation(line: 2, column: 16, scope: !7) diff --git a/llvm/test/CodeGen/X86/stack-protector.ll b/llvm/test/CodeGen/X86/stack-protector.ll index 4355946ccc8..5a2dc3e34fb 100644 --- a/llvm/test/CodeGen/X86/stack-protector.ll +++ b/llvm/test/CodeGen/X86/stack-protector.ll @@ -5,6 +5,7 @@ ; RUN: llc -mtriple=amd64-pc-openbsd < %s -o - | FileCheck --check-prefix=OPENBSD-AMD64 %s ; RUN: llc -mtriple=i386-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-I386 %s ; RUN: llc -mtriple=x86_64-w64-mingw32 < %s -o - | FileCheck --check-prefix=MINGW-X64 %s +; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=IGNORE_INTRIN %s %struct.foo = type { [16 x i8] } %struct.foo.0 = type { [4 x i8] } @@ -4081,6 +4082,20 @@ entry: ret void, !dbg !9 } +define i32 @IgnoreIntrinsicTest() #1 { +; IGNORE_INTRIN: IgnoreIntrinsicTest: + %1 = alloca i32, align 4 + %2 = bitcast i32* %1 to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %2) + store volatile i32 1, i32* %1, align 4 + %3 = load volatile i32, i32* %1, align 4 + %4 = mul nsw i32 %3, 42 + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %2) + ret i32 %4 +; IGNORE_INTRIN-NOT: callq __stack_chk_fail +; IGNORE_INTRIN: .cfi_endproc +} + declare double @testi_aux() declare i8* @strcpy(i8*, i8*) declare i32 @printf(i8*, ...) @@ -4093,6 +4108,8 @@ declare i32 @__gxx_personality_v0(...) declare i32* @getp() declare i32 @dummy(...) declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1) +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) attributes #0 = { ssp } attributes #1 = { sspstrong } |