From aa84f050fcac97a66813fe446296c8f796e755f7 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Fri, 16 Sep 2016 22:04:10 +0000 Subject: [PATCH] [safestack] Fix assertion failure in stack coloring. This is a fix for PR30318. Clang may generate IR where an alloca is already live when entering a BB with lifetime.start. In this case, conservatively extend the alloca lifetime all the way back to the block entry. llvm-svn: 281784 --- llvm/lib/CodeGen/SafeStackColoring.cpp | 10 +++++--- llvm/test/Transforms/SafeStack/coloring2.ll | 39 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/SafeStackColoring.cpp b/llvm/lib/CodeGen/SafeStackColoring.cpp index 795eb8d..7fbeadd 100644 --- a/llvm/lib/CodeGen/SafeStackColoring.cpp +++ b/llvm/lib/CodeGen/SafeStackColoring.cpp @@ -214,10 +214,12 @@ void StackColoring::calculateLiveIntervals() { unsigned AllocaNo = It.second.AllocaNo; if (IsStart) { - assert(!Started.test(AllocaNo)); - Started.set(AllocaNo); - Ended.reset(AllocaNo); - Start[AllocaNo] = InstNo; + assert(!Started.test(AllocaNo) || Start[AllocaNo] == BBStart); + if (!Started.test(AllocaNo)) { + Started.set(AllocaNo); + Ended.reset(AllocaNo); + Start[AllocaNo] = InstNo; + } } else { assert(!Ended.test(AllocaNo)); if (Started.test(AllocaNo)) { diff --git a/llvm/test/Transforms/SafeStack/coloring2.ll b/llvm/test/Transforms/SafeStack/coloring2.ll index 54ed812..f3ac6d7 100644 --- a/llvm/test/Transforms/SafeStack/coloring2.ll +++ b/llvm/test/Transforms/SafeStack/coloring2.ll @@ -474,6 +474,45 @@ entry: ret i32 %z3 } +define void @end_loop() safestack { +; CHECK-LABEL: define void @end_loop() +entry: +; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr +; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16 + %x = alloca i8, align 4 + call void @llvm.lifetime.start(i64 4, i8* %x) nounwind + br label %l2 + +l2: + call void @capture8(i8* %x) + call void @llvm.lifetime.end(i64 4, i8* %x) nounwind + br label %l2 +} + +; Check that @x and @y get distinct stack slots => @x lifetime does not break +; when control re-enters l2. +define void @start_loop() safestack { +; CHECK-LABEL: define void @start_loop() +entry: +; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr +; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16 + %x = alloca i8, align 4 + %y = alloca i8, align 4 + call void @llvm.lifetime.start(i64 4, i8* %x) nounwind + br label %l2 + +l2: +; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 + call void @llvm.lifetime.start(i64 4, i8* %y) nounwind + call void @capture8(i8* %y) + call void @llvm.lifetime.end(i64 4, i8* %y) nounwind + +; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 + call void @llvm.lifetime.start(i64 4, i8* %x) nounwind + call void @capture8(i8* %x) + br label %l2 +} + declare void @llvm.lifetime.start(i64, i8* nocapture) declare void @llvm.lifetime.end(i64, i8* nocapture) declare void @capture8(i8*) -- 2.7.4