Imported Upstream version 5.18.0.167

Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-20 08:25:10 +00:00
parent e19d552987
commit b084638f15
28489 changed files with 184 additions and 3866856 deletions

View File

@ -1,18 +0,0 @@
; RUN: opt < %s -basicaa -sink -S | FileCheck %s
declare void @foo(i64 *)
define i64 @sinkload(i1 %cmp) {
; CHECK-LABEL: @sinkload
top:
%a = alloca i64
; CHECK: call void @foo(i64* %a)
; CHECK-NEXT: %x = load i64, i64* %a
call void @foo(i64* %a)
%x = load i64, i64* %a
br i1 %cmp, label %A, label %B
A:
store i64 0, i64 *%a
br label %B
B:
; CHECK-NOT: load i64, i64 *%a
ret i64 %x
}

View File

@ -1,144 +0,0 @@
; RUN: opt < %s -basicaa -sink -S | FileCheck %s
; RUN: opt < %s -aa-pipeline='basic-aa' -passes='sink' -S | FileCheck %s
@A = external global i32
@B = external global i32
; Sink should sink the load past the store (which doesn't overlap) into
; the block that uses it.
; CHECK-LABEL: @foo(
; CHECK: true:
; CHECK-NEXT: %l = load i32, i32* @A
; CHECK-NEXT: ret i32 %l
define i32 @foo(i1 %z) {
%l = load i32, i32* @A
store i32 0, i32* @B
br i1 %z, label %true, label %false
true:
ret i32 %l
false:
ret i32 0
}
; But don't sink load volatiles...
; CHECK-LABEL: @foo2(
; CHECK: load volatile
; CHECK-NEXT: store i32
define i32 @foo2(i1 %z) {
%l = load volatile i32, i32* @A
store i32 0, i32* @B
br i1 %z, label %true, label %false
true:
ret i32 %l
false:
ret i32 0
}
; Sink to the nearest post-dominator
; CHECK-LABEL: @diamond(
; CHECK: X:
; CHECK-NEXT: phi
; CHECK-NEXT: mul nsw
; CHECK-NEXT: sub
define i32 @diamond(i32 %a, i32 %b, i32 %c) {
%1 = mul nsw i32 %c, %b
%2 = icmp sgt i32 %a, 0
br i1 %2, label %B0, label %B1
B0: ; preds = %0
br label %X
B1: ; preds = %0
br label %X
X: ; preds = %5, %3
%.01 = phi i32 [ %c, %B0 ], [ %a, %B1 ]
%R = sub i32 %1, %.01
ret i32 %R
}
; We shouldn't sink constant sized allocas from the entry block, since CodeGen
; interprets allocas outside the entry block as dynamically sized stack objects.
; CHECK-LABEL: @alloca_nosink
; CHECK: entry:
; CHECK-NEXT: alloca
define i32 @alloca_nosink(i32 %a, i32 %b) {
entry:
%0 = alloca i32
%1 = icmp ne i32 %a, 0
br i1 %1, label %if, label %endif
if:
%2 = getelementptr i32, i32* %0, i32 1
store i32 0, i32* %0
store i32 1, i32* %2
%3 = getelementptr i32, i32* %0, i32 %b
%4 = load i32, i32* %3
ret i32 %4
endif:
ret i32 0
}
; Make sure we sink dynamic sized allocas
; CHECK-LABEL: @alloca_sink_dynamic
; CHECK: entry:
; CHECK-NOT: alloca
; CHECK: if:
; CHECK-NEXT: alloca
define i32 @alloca_sink_dynamic(i32 %a, i32 %b, i32 %size) {
entry:
%0 = alloca i32, i32 %size
%1 = icmp ne i32 %a, 0
br i1 %1, label %if, label %endif
if:
%2 = getelementptr i32, i32* %0, i32 1
store i32 0, i32* %0
store i32 1, i32* %2
%3 = getelementptr i32, i32* %0, i32 %b
%4 = load i32, i32* %3
ret i32 %4
endif:
ret i32 0
}
; We also want to sink allocas that are not in the entry block. These
; will already be considered as dynamically sized stack objects, so sinking
; them does no further damage.
; CHECK-LABEL: @alloca_sink_nonentry
; CHECK: if0:
; CHECK-NOT: alloca
; CHECK: if:
; CHECK-NEXT: alloca
define i32 @alloca_sink_nonentry(i32 %a, i32 %b, i32 %c) {
entry:
%cmp = icmp ne i32 %c, 0
br i1 %cmp, label %endif, label %if0
if0:
%0 = alloca i32
%1 = icmp ne i32 %a, 0
br i1 %1, label %if, label %endif
if:
%2 = getelementptr i32, i32* %0, i32 1
store i32 0, i32* %0
store i32 1, i32* %2
%3 = getelementptr i32, i32* %0, i32 %b
%4 = load i32, i32* %3
ret i32 %4
endif:
ret i32 0
}

View File

@ -1,112 +0,0 @@
; RUN: opt < %s -basicaa -sink -S | FileCheck %s
declare i32 @f_load_global() nounwind readonly
declare i32 @f_load_arg(i32*) nounwind readonly argmemonly
declare void @f_store_global(i32) nounwind
declare void @f_store_arg(i32*) nounwind argmemonly
declare void @f_readonly_arg(i32* readonly, i32*) nounwind argmemonly
declare i32 @f_readnone(i32) nounwind readnone
@A = external global i32
@B = external global i32
; Sink readonly call if no stores are in the way.
;
; CHECK-LABEL: @test_sink_no_stores(
; CHECK: true:
; CHECK-NEXT: %l = call i32 @f_load_global
; CHECK-NEXT: ret i32 %l
define i32 @test_sink_no_stores(i1 %z) {
%l = call i32 @f_load_global()
br i1 %z, label %true, label %false
true:
ret i32 %l
false:
ret i32 0
}
; CHECK-LABEL: @test_sink_argmem_store(
; CHECK: true:
; CHECK-NEXT: %l = call i32 @f_load_arg
; CHECK-NEXT: ret i32 %l
define i32 @test_sink_argmem_store(i1 %z) {
%l = call i32 @f_load_arg(i32* @A)
store i32 0, i32* @B
br i1 %z, label %true, label %false
true:
ret i32 %l
false:
ret i32 0
}
; CHECK-LABEL: @test_sink_argmem_call(
; CHECK: true:
; CHECK-NEXT: %l = call i32 @f_load_arg
; CHECK-NEXT: ret i32 %l
define i32 @test_sink_argmem_call(i1 %z) {
%l = call i32 @f_load_arg(i32* @A)
call void @f_store_arg(i32* @B)
br i1 %z, label %true, label %false
true:
ret i32 %l
false:
ret i32 0
}
; CHECK-LABEL: @test_sink_argmem_multiple(
; CHECK: true:
; CHECK-NEXT: %l = call i32 @f_load_arg
; CHECK-NEXT: ret i32 %l
define i32 @test_sink_argmem_multiple(i1 %z) {
%l = call i32 @f_load_arg(i32* @A)
call void @f_readonly_arg(i32* @A, i32* @B)
br i1 %z, label %true, label %false
true:
ret i32 %l
false:
ret i32 0
}
; But don't sink if there is a store.
;
; CHECK-LABEL: @test_nosink_store(
; CHECK: call i32 @f_load_global
; CHECK-NEXT: store i32
define i32 @test_nosink_store(i1 %z) {
%l = call i32 @f_load_global()
store i32 0, i32* @A
br i1 %z, label %true, label %false
true:
ret i32 %l
false:
ret i32 0
}
; CHECK-LABEL: @test_nosink_call(
; CHECK: call i32 @f_load_global
; CHECK-NEXT: call void @f_store_global
define i32 @test_nosink_call(i1 %z) {
%l = call i32 @f_load_global()
call void @f_store_global(i32 0)
br i1 %z, label %true, label %false
true:
ret i32 %l
false:
ret i32 0
}
; readnone calls are sunk across stores.
;
; CHECK-LABEL: @test_sink_readnone(
; CHECK: true:
; CHECK-NEXT: %l = call i32 @f_readnone(
; CHECK-NEXT: ret i32 %l
define i32 @test_sink_readnone(i1 %z) {
%l = call i32 @f_readnone(i32 0)
store i32 0, i32* @A
br i1 %z, label %true, label %false
true:
ret i32 %l
false:
ret i32 0
}

View File

@ -1,37 +0,0 @@
; RUN: opt -sink -S < %s | FileCheck %s
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc"
define void @h() personality i32 (...)* @__CxxFrameHandler3 {
entry:
%call = call i32 @g(i32 1) readnone
invoke void @_CxxThrowException(i8* null, i8* null) noreturn
to label %unreachable unwind label %catch.dispatch
catch.dispatch: ; preds = %entry
%cs = catchswitch within none [label %catch] unwind to caller
catch: ; preds = %catch.dispatch
%cp = catchpad within %cs [i8* null, i32 64, i8* null]
catchret from %cp to label %try.cont
try.cont: ; preds = %catch
call void @k(i32 %call)
ret void
unreachable: ; preds = %entry
unreachable
}
declare x86_stdcallcc void @_CxxThrowException(i8*, i8*)
declare i32 @__CxxFrameHandler3(...)
declare i32 @g(i32) readnone
declare void @k(i32)
; CHECK-LABEL: define void @h(
; CHECK: call i32 @g(i32 1)
; CHECK-NEXT: invoke void @_CxxThrowException(

View File

@ -1,23 +0,0 @@
; RUN: opt -sink -S < %s | FileCheck %s
; Verify that IR sinking does not move convergent operations to
; blocks that are not control equivalent.
; CHECK: define i32 @foo
; CHECK: entry
; CHECK-NEXT: call i32 @bar
; CHECK-NEXT: br i1 %arg
define i32 @foo(i1 %arg) {
entry:
%c = call i32 @bar() readonly convergent
br i1 %arg, label %then, label %end
then:
ret i32 %c
end:
ret i32 0
}
declare i32 @bar() readonly convergent

View File

@ -1,28 +0,0 @@
; RUN: opt -S -sink < %s | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define void @test1(i32* ()*) {
entry:
%1 = call i32* %0() #0
fence syncscope("singlethread") seq_cst
%2 = load i32, i32* %1, align 4
fence syncscope("singlethread") seq_cst
%3 = icmp eq i32 %2, 0
br i1 %3, label %fail, label %pass
fail: ; preds = %top
br label %pass
pass: ; preds = %fail, %top
ret void
}
; CHECK-LABEL: @test1(
; CHECK: %[[call:.*]] = call i32* %0()
; CHECK: fence syncscope("singlethread") seq_cst
; CHECK: load i32, i32* %[[call]], align 4
; CHECK: fence syncscope("singlethread") seq_cst
attributes #0 = { nounwind readnone }

View File

@ -1,33 +0,0 @@
; Test that we don't sink landingpads
; RUN: opt -sink -S < %s | FileCheck %s
declare hidden void @g()
declare void @h()
declare i32 @__gxx_personality_v0(...)
define void @f() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
entry:
invoke void @g()
to label %invoke.cont.15 unwind label %lpad
invoke.cont.15:
unreachable
; CHECK: lpad:
; CHECK: %0 = landingpad { i8*, i32 }
lpad:
%0 = landingpad { i8*, i32 }
catch i8* null
invoke void @h()
to label %invoke.cont unwind label %lpad.1
; CHECK: invoke.cont
; CHECK-NOT: %0 = landingpad { i8*, i32 }
invoke.cont:
ret void
lpad.1:
%1 = landingpad { i8*, i32 }
cleanup
resume { i8*, i32 } %1
}