mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-19 15:13:49 -04:00
[safestack] Sink unsafe address computation to each use.
This is a fix for PR27844. When replacing uses of unsafe allocas, emit the new location immediately after each use. Without this, the pointer stays live from the function entry to the last use, while it's usually cheaper to recalculate. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272969 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -13,16 +13,15 @@ entry:
|
||||
|
||||
; CHECK: store i8* %[[USST]], i8** @__safestack_unsafe_stack_ptr
|
||||
|
||||
; CHECK: %[[AADDR:.*]] = alloca i8*, align 8
|
||||
%a.addr = alloca i8*, align 8
|
||||
|
||||
; CHECK: %[[BUFPTR:.*]] = getelementptr i8, i8* %[[USP]], i32 -16
|
||||
; CHECK: %[[BUFPTR2:.*]] = bitcast i8* %[[BUFPTR]] to [16 x i8]*
|
||||
%buf = alloca [16 x i8], align 16
|
||||
|
||||
; CHECK: %[[AADDR:.*]] = alloca i8*, align 8
|
||||
; CHECK: store i8* {{.*}}, i8** %[[AADDR]], align 8
|
||||
store i8* %a, i8** %a.addr, align 8
|
||||
|
||||
; CHECK: %[[BUFPTR:.*]] = getelementptr i8, i8* %[[USP]], i32 -16
|
||||
; CHECK: %[[BUFPTR2:.*]] = bitcast i8* %[[BUFPTR]] to [16 x i8]*
|
||||
; CHECK: %[[GEP:.*]] = getelementptr inbounds [16 x i8], [16 x i8]* %[[BUFPTR2]], i32 0, i32 0
|
||||
%gep = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
|
||||
|
||||
|
||||
@@ -17,16 +17,15 @@ entry:
|
||||
|
||||
; CHECK: store i8* %[[USST]], i8** @__safestack_unsafe_stack_ptr
|
||||
|
||||
; CHECK: %[[AADDR:.*]] = alloca i8*, align 8
|
||||
%a.addr = alloca i8*, align 8
|
||||
|
||||
; CHECK: %[[BUFPTR:.*]] = getelementptr i8, i8* %[[USP]], i32 -4
|
||||
; CHECK: %[[BUFPTR2:.*]] = bitcast i8* %[[BUFPTR]] to [4 x i8]*
|
||||
%buf = alloca [4 x i8], align 1
|
||||
|
||||
; CHECK: %[[AADDR:.*]] = alloca i8*, align 8
|
||||
; CHECK: store i8* {{.*}}, i8** %[[AADDR]], align 8
|
||||
store i8* %a, i8** %a.addr, align 8
|
||||
|
||||
; CHECK: %[[BUFPTR:.*]] = getelementptr i8, i8* %[[USP]], i32 -4
|
||||
; CHECK: %[[BUFPTR2:.*]] = bitcast i8* %[[BUFPTR]] to [4 x i8]*
|
||||
; CHECK: %[[GEP:.*]] = getelementptr inbounds [4 x i8], [4 x i8]* %[[BUFPTR2]], i32 0, i32 0
|
||||
%gep = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s
|
||||
; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s
|
||||
|
||||
define void @f(i1 %d1, i1 %d2) safestack {
|
||||
entry:
|
||||
; CHECK-LABEL: define void @f(
|
||||
; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
|
||||
; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16
|
||||
; CHECK: br i1 %d1, label %[[BB0:.*]], label %[[BB1:.*]]
|
||||
%a = alloca i32, align 8
|
||||
%b = alloca i32, align 8
|
||||
br i1 %d1, label %bb0, label %bb1
|
||||
|
||||
bb0:
|
||||
; CHECK: [[BB0]]:
|
||||
; CHECK: %[[Ai8:.*]] = getelementptr i8, i8* %unsafe_stack_ptr, i32
|
||||
; CHECK: %[[AUNSAFE:.*]] = bitcast i8* %[[Ai8]] to i32*
|
||||
; CHECK: br i1
|
||||
br i1 %d2, label %bb2, label %bb2
|
||||
|
||||
bb1:
|
||||
; CHECK: [[BB1]]:
|
||||
; CHECK: %[[Bi8:.*]] = getelementptr i8, i8* %unsafe_stack_ptr, i32
|
||||
; CHECK: %[[BUNSAFE:.*]] = bitcast i8* %[[Bi8]] to i32*
|
||||
; CHECK: br label
|
||||
br label %bb2
|
||||
|
||||
bb2:
|
||||
; CHECK: phi i32* [ %[[AUNSAFE]], %[[BB0]] ], [ %[[AUNSAFE]], %[[BB0]] ], [ %[[BUNSAFE]], %[[BB1]] ]
|
||||
%c = phi i32* [ %a, %bb0 ], [ %a, %bb0 ], [ %b, %bb1 ]
|
||||
call void @capture(i32* %c)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @capture(i32*)
|
||||
@@ -0,0 +1,22 @@
|
||||
; Test that unsafe alloca address calculation is done immediately before each use.
|
||||
; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s
|
||||
; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s
|
||||
|
||||
define void @f() safestack {
|
||||
entry:
|
||||
%x0 = alloca i32, align 4
|
||||
%x1 = alloca i32, align 4
|
||||
|
||||
; CHECK: %[[A:.*]] = getelementptr i8, i8* %{{.*}}, i32 -4
|
||||
; CHECK: %[[X0:.*]] = bitcast i8* %[[A]] to i32*
|
||||
; CHECK: call void @use(i32* %[[X0]])
|
||||
call void @use(i32* %x0)
|
||||
|
||||
; CHECK: %[[B:.*]] = getelementptr i8, i8* %{{.*}}, i32 -8
|
||||
; CHECK: %[[X1:.*]] = bitcast i8* %[[B]] to i32*
|
||||
; CHECK: call void @use(i32* %[[X1]])
|
||||
call void @use(i32* %x1)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @use(i32*)
|
||||
@@ -15,16 +15,15 @@ entry:
|
||||
|
||||
; CHECK: store i8* %[[USST]], i8** @__safestack_unsafe_stack_ptr
|
||||
|
||||
; CHECK: %[[AADDR:.*]] = alloca i8*, align 8
|
||||
%a.addr = alloca i8*, align 8
|
||||
|
||||
; CHECK: %[[BUFPTR:.*]] = getelementptr i8, i8* %[[USP]], i32 -16
|
||||
; CHECK: %[[BUFPTR2:.*]] = bitcast i8* %[[BUFPTR]] to %struct.foo*
|
||||
%buf = alloca %struct.foo, align 1
|
||||
|
||||
; CHECK: %[[AADDR:.*]] = alloca i8*, align 8
|
||||
; CHECK: store i8* {{.*}}, i8** %[[AADDR]], align 8
|
||||
store i8* %a, i8** %a.addr, align 8
|
||||
|
||||
; CHECK: %[[BUFPTR:.*]] = getelementptr i8, i8* %[[USP]], i32 -16
|
||||
; CHECK: %[[BUFPTR2:.*]] = bitcast i8* %[[BUFPTR]] to %struct.foo*
|
||||
; CHECK: %[[GEP:.*]] = getelementptr inbounds %struct.foo, %struct.foo* %[[BUFPTR2]], i32 0, i32 0, i32 0
|
||||
%gep = getelementptr inbounds %struct.foo, %struct.foo* %buf, i32 0, i32 0, i32 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user