diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-08-17 19:33:52 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-08-17 19:33:52 +0000 |
| commit | a7fe922b98bb45be7dce7c1cfe668ec27eeddc74 (patch) | |
| tree | e9648f5bddc775b842e53141d7c9748482f7115a /test/Transforms | |
| parent | c3aee98e721333f265a88d6bf348e6e468f027d4 (diff) | |
Notes
Diffstat (limited to 'test/Transforms')
| -rw-r--r-- | test/Transforms/ConstProp/calls.ll | 88 | ||||
| -rw-r--r-- | test/Transforms/EarlyCSE/basic.ll | 14 | ||||
| -rw-r--r-- | test/Transforms/GlobalOpt/metadata.ll | 2 | ||||
| -rw-r--r-- | test/Transforms/IndVarSimplify/pr28935.ll | 20 | ||||
| -rw-r--r-- | test/Transforms/Inline/inalloca-not-static.ll | 63 | ||||
| -rw-r--r-- | test/Transforms/Inline/inline_constprop.ll | 43 | ||||
| -rw-r--r-- | test/Transforms/InstCombine/call.ll | 11 | ||||
| -rw-r--r-- | test/Transforms/InstCombine/log-pow.ll | 3 | ||||
| -rw-r--r-- | test/Transforms/InstCombine/select.ll | 23 | ||||
| -rw-r--r-- | test/Transforms/LCSSA/pr28424.ll | 87 | ||||
| -rw-r--r-- | test/Transforms/LCSSA/pr28608.ll | 35 | ||||
| -rw-r--r-- | test/Transforms/LoopSimplify/pr28272.ll | 76 | ||||
| -rw-r--r-- | test/Transforms/LoopStrengthReduce/X86/pr28719.ll | 47 | ||||
| -rw-r--r-- | test/Transforms/LoopVectorize/pr28541.ll | 71 | ||||
| -rw-r--r-- | test/Transforms/SafeStack/coloring-ssp.ll | 34 | ||||
| -rw-r--r-- | test/Transforms/SafeStack/layout-region-split.ll | 84 |
16 files changed, 656 insertions, 45 deletions
diff --git a/test/Transforms/ConstProp/calls.ll b/test/Transforms/ConstProp/calls.ll index a445ac81ff27..d9a884a4a7bc 100644 --- a/test/Transforms/ConstProp/calls.ll +++ b/test/Transforms/ConstProp/calls.ll @@ -1,47 +1,47 @@ ; RUN: opt < %s -constprop -S | FileCheck %s ; RUN: opt < %s -constprop -disable-simplify-libcalls -S | FileCheck %s --check-prefix=FNOBUILTIN -declare double @acos(double) -declare double @asin(double) -declare double @atan(double) -declare double @atan2(double, double) -declare double @ceil(double) -declare double @cos(double) -declare double @cosh(double) -declare double @exp(double) -declare double @exp2(double) -declare double @fabs(double) -declare double @floor(double) -declare double @fmod(double, double) -declare double @log(double) -declare double @log10(double) -declare double @pow(double, double) -declare double @sin(double) -declare double @sinh(double) -declare double @sqrt(double) -declare double @tan(double) -declare double @tanh(double) +declare double @acos(double) readnone nounwind +declare double @asin(double) readnone nounwind +declare double @atan(double) readnone nounwind +declare double @atan2(double, double) readnone nounwind +declare double @ceil(double) readnone nounwind +declare double @cos(double) readnone nounwind +declare double @cosh(double) readnone nounwind +declare double @exp(double) readnone nounwind +declare double @exp2(double) readnone nounwind +declare double @fabs(double) readnone nounwind +declare double @floor(double) readnone nounwind +declare double @fmod(double, double) readnone nounwind +declare double @log(double) readnone nounwind +declare double @log10(double) readnone nounwind +declare double @pow(double, double) readnone nounwind +declare double @sin(double) readnone nounwind +declare double @sinh(double) readnone nounwind +declare double @sqrt(double) readnone nounwind +declare double @tan(double) readnone nounwind +declare double @tanh(double) readnone nounwind -declare float @acosf(float) -declare float @asinf(float) -declare float @atanf(float) -declare float @atan2f(float, float) -declare float @ceilf(float) -declare float @cosf(float) -declare float @coshf(float) -declare float @expf(float) -declare float @exp2f(float) -declare float @fabsf(float) -declare float @floorf(float) -declare float @fmodf(float, float) -declare float @logf(float) -declare float @log10f(float) -declare float @powf(float, float) -declare float @sinf(float) -declare float @sinhf(float) -declare float @sqrtf(float) -declare float @tanf(float) -declare float @tanhf(float) +declare float @acosf(float) readnone nounwind +declare float @asinf(float) readnone nounwind +declare float @atanf(float) readnone nounwind +declare float @atan2f(float, float) readnone nounwind +declare float @ceilf(float) readnone nounwind +declare float @cosf(float) readnone nounwind +declare float @coshf(float) readnone nounwind +declare float @expf(float) readnone nounwind +declare float @exp2f(float) readnone nounwind +declare float @fabsf(float) readnone nounwind +declare float @floorf(float) readnone nounwind +declare float @fmodf(float, float) readnone nounwind +declare float @logf(float) readnone nounwind +declare float @log10f(float) readnone nounwind +declare float @powf(float, float) readnone nounwind +declare float @sinf(float) readnone nounwind +declare float @sinhf(float) readnone nounwind +declare float @sqrtf(float) readnone nounwind +declare float @tanf(float) readnone nounwind +declare float @tanhf(float) readnone nounwind define double @T() { ; CHECK-LABEL: @T( @@ -193,11 +193,13 @@ entry: ret i1 %b } -; TODO: Inexact values should not fold as they are dependent on rounding mode +; Inexact values should not fold as they are dependent on rounding mode define i1 @test_sse_cvts_inexact() nounwind readnone { ; CHECK-LABEL: @test_sse_cvts_inexact( -; CHECK-NOT: call -; CHECK: ret i1 true +; CHECK: call +; CHECK: call +; CHECK: call +; CHECK: call entry: %i0 = tail call i32 @llvm.x86.sse.cvtss2si(<4 x float> <float 1.75, float undef, float undef, float undef>) nounwind %i1 = tail call i64 @llvm.x86.sse.cvtss2si64(<4 x float> <float 1.75, float undef, float undef, float undef>) nounwind diff --git a/test/Transforms/EarlyCSE/basic.ll b/test/Transforms/EarlyCSE/basic.ll index fa1a7059db95..3c427d899f68 100644 --- a/test/Transforms/EarlyCSE/basic.ll +++ b/test/Transforms/EarlyCSE/basic.ll @@ -276,3 +276,17 @@ define void @dse_neg2(i32 *%P) { ret void } +@c = external global i32, align 4 +declare i32 @reads_c(i32 returned) +define void @pr28763() { +entry: +; CHECK-LABEL: @pr28763( +; CHECK: store i32 0, i32* @c, align 4 +; CHECK: call i32 @reads_c(i32 0) +; CHECK: store i32 2, i32* @c, align 4 + %load = load i32, i32* @c, align 4 + store i32 0, i32* @c, align 4 + %call = call i32 @reads_c(i32 0) + store i32 2, i32* @c, align 4 + ret void +} diff --git a/test/Transforms/GlobalOpt/metadata.ll b/test/Transforms/GlobalOpt/metadata.ll index 152d58e6e320..b766349d506b 100644 --- a/test/Transforms/GlobalOpt/metadata.ll +++ b/test/Transforms/GlobalOpt/metadata.ll @@ -28,5 +28,5 @@ declare void @llvm.foo(metadata, metadata) nounwind readnone ; CHECK: !named = !{![[NULL:[0-9]+]]} !0 = !{i8*** @G} -; CHECK-DAG: ![[NULL]] = !{null} +; CHECK-DAG: ![[NULL]] = distinct !{null} ; CHECK-DAG: ![[EMPTY]] = !{} diff --git a/test/Transforms/IndVarSimplify/pr28935.ll b/test/Transforms/IndVarSimplify/pr28935.ll new file mode 100644 index 000000000000..0cfd1d31a41d --- /dev/null +++ b/test/Transforms/IndVarSimplify/pr28935.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -indvars < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare i16 @fn1(i16 returned, i64) + +define void @fn2() { +; CHECK-LABEL: @fn2( +entry: + br label %for.cond + +for.cond: + %f.0 = phi i64 [ undef, %entry ], [ %inc, %for.cond ] + %conv = trunc i64 %f.0 to i16 + %call = tail call i16 @fn1(i16 %conv, i64 %f.0) + %conv2 = zext i16 %call to i32 + %inc = add nsw i64 %f.0, 1 + br label %for.cond +} diff --git a/test/Transforms/Inline/inalloca-not-static.ll b/test/Transforms/Inline/inalloca-not-static.ll new file mode 100644 index 000000000000..e70e30d1a7ed --- /dev/null +++ b/test/Transforms/Inline/inalloca-not-static.ll @@ -0,0 +1,63 @@ +; RUN: opt -always-inline -S < %s | FileCheck %s + +; We used to misclassify inalloca as a static alloca in the inliner. This only +; arose with for alwaysinline functions, because the normal inliner refuses to +; inline such things. + +; Generated using this C++ source: +; struct Foo { +; Foo(); +; Foo(const Foo &o); +; ~Foo(); +; int a; +; }; +; __forceinline void h(Foo o) {} +; __forceinline void g() { h(Foo()); } +; void f() { g(); } + +; ModuleID = 't.cpp' +source_filename = "t.cpp" +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i386-pc-windows-msvc19.0.24210" + +%struct.Foo = type { i32 } + +declare i8* @llvm.stacksave() +declare void @llvm.stackrestore(i8*) + +declare x86_thiscallcc %struct.Foo* @"\01??0Foo@@QAE@XZ"(%struct.Foo* returned) unnamed_addr +declare x86_thiscallcc void @"\01??1Foo@@QAE@XZ"(%struct.Foo*) unnamed_addr + +define void @f() { +entry: + call void @g() + ret void +} + +define internal void @g() alwaysinline { +entry: + %inalloca.save = call i8* @llvm.stacksave() + %argmem = alloca inalloca <{ %struct.Foo }>, align 4 + %0 = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %argmem, i32 0, i32 0 + %call = call x86_thiscallcc %struct.Foo* @"\01??0Foo@@QAE@XZ"(%struct.Foo* %0) + call void @h(<{ %struct.Foo }>* inalloca %argmem) + call void @llvm.stackrestore(i8* %inalloca.save) + ret void +} + +; Function Attrs: alwaysinline inlinehint nounwind +define internal void @h(<{ %struct.Foo }>* inalloca) alwaysinline { +entry: + %o = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 + call x86_thiscallcc void @"\01??1Foo@@QAE@XZ"(%struct.Foo* %o) + ret void +} + +; CHECK: define void @f() +; CHECK: %inalloca.save.i = call i8* @llvm.stacksave() +; CHECK: alloca inalloca <{ %struct.Foo }>, align 4 +; CHECK: %call.i = call x86_thiscallcc %struct.Foo* @"\01??0Foo@@QAE@XZ"(%struct.Foo* %0) +; CHECK: %o.i.i = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %argmem.i, i32 0, i32 0 +; CHECK: call x86_thiscallcc void @"\01??1Foo@@QAE@XZ"(%struct.Foo* %o.i.i) +; CHECK: call void @llvm.stackrestore(i8* %inalloca.save.i) +; CHECK: ret void diff --git a/test/Transforms/Inline/inline_constprop.ll b/test/Transforms/Inline/inline_constprop.ll index de23b6157a71..ab9e90ca27c6 100644 --- a/test/Transforms/Inline/inline_constprop.ll +++ b/test/Transforms/Inline/inline_constprop.ll @@ -279,3 +279,46 @@ return: %retval.0 = phi i32* [ %b, %if.end3 ], [ %a, %if.then ] ret i32* %retval.0 } + +declare i32 @PR28802.external(i32 returned %p1) + +define internal i32 @PR28802.callee() { +entry: + br label %cont + +cont: + %0 = phi i32 [ 0, %entry ] + %call = call i32 @PR28802.external(i32 %0) + ret i32 %call +} + +define i32 @PR28802() { +entry: + %call = call i32 @PR28802.callee() + ret i32 %call +} + +; CHECK-LABEL: define i32 @PR28802( +; CHECK: call i32 @PR28802.external(i32 0) +; CHECK: ret i32 0 + +define internal i32 @PR28848.callee(i32 %p2, i1 %c) { +entry: + br i1 %c, label %cond.end, label %cond.true + +cond.true: + br label %cond.end + +cond.end: + %cond = phi i32 [ 0, %cond.true ], [ %p2, %entry ] + %or = or i32 %cond, %p2 + ret i32 %or +} + +define i32 @PR28848() { +entry: + %call = call i32 @PR28848.callee(i32 0, i1 false) + ret i32 %call +} +; CHECK-LABEL: define i32 @PR28848( +; CHECK: ret i32 0 diff --git a/test/Transforms/InstCombine/call.ll b/test/Transforms/InstCombine/call.ll index ea338f0bf581..5307dcb6df72 100644 --- a/test/Transforms/InstCombine/call.ll +++ b/test/Transforms/InstCombine/call.ll @@ -276,3 +276,14 @@ define <2 x i16> @test16() { %X = call <2 x i16> bitcast (i32 ()* @test16a to <2 x i16> ()*)( ) ret <2 x i16> %X } + +declare i32 @pr28655(i32 returned %V) + +define i32 @test17() { +entry: + %C = call i32 @pr28655(i32 0) + ret i32 %C +} +; CHECK-LABEL: @test17( +; CHECK: call i32 @pr28655(i32 0) +; CHECK: ret i32 0 diff --git a/test/Transforms/InstCombine/log-pow.ll b/test/Transforms/InstCombine/log-pow.ll index a0c10d0a0b8c..4e4a2b2612c7 100644 --- a/test/Transforms/InstCombine/log-pow.ll +++ b/test/Transforms/InstCombine/log-pow.ll @@ -55,7 +55,8 @@ define double @log_exp2_not_fast(double %x) { ; CHECK-NEXT: %call3 = call fast double @log(double %call2) ; CHECK-NEXT: ret double %call3 -declare double @log(double) +declare double @log(double) #0 declare double @exp2(double) declare double @llvm.pow.f64(double, double) +attributes #0 = { nounwind readnone } diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index e0e7bfccff93..413be89c42e7 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -1737,3 +1737,26 @@ define i32 @PR27137(i32 %a) { %s1 = select i1 %c1, i32 %s0, i32 -1 ret i32 %s1 } + +define i32 @select_icmp_slt0_xor(i32 %x) { +; CHECK-LABEL: @select_icmp_slt0_xor( +; CHECK-NEXT: [[TMP1:%.*]] = or i32 %x, -2147483648 +; CHECK-NEXT: ret i32 [[TMP1]] +; + %cmp = icmp slt i32 %x, zeroinitializer + %xor = xor i32 %x, 2147483648 + %x.xor = select i1 %cmp, i32 %x, i32 %xor + ret i32 %x.xor +} + +define <2 x i32> @select_icmp_slt0_xor_vec(<2 x i32> %x) { +; CHECK-LABEL: @select_icmp_slt0_xor_vec( +; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> %x, <i32 -2147483648, i32 -2147483648> +; CHECK-NEXT: ret <2 x i32> [[TMP1]] +; + %cmp = icmp slt <2 x i32> %x, zeroinitializer + %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648> + %x.xor = select <2 x i1> %cmp, <2 x i32> %x, <2 x i32> %xor + ret <2 x i32> %x.xor +} + diff --git a/test/Transforms/LCSSA/pr28424.ll b/test/Transforms/LCSSA/pr28424.ll new file mode 100644 index 000000000000..cd7969009fbb --- /dev/null +++ b/test/Transforms/LCSSA/pr28424.ll @@ -0,0 +1,87 @@ +; RUN: opt < %s -lcssa -S -o - | FileCheck %s +target triple = "x86_64-unknown-linux-gnu" + +; PR28424 +; Here LCSSA adds phi-nodes for %x into the loop exits. Then, SSAUpdater needs +; to insert phi-nodes to merge these values. That creates a new def, which in +; its turn needs another LCCSA phi-node, and this test ensures that we insert +; it. + +; CHECK-LABEL: @foo1 +define internal i32 @foo1() { +entry: + br label %header + +header: + %x = add i32 0, 1 + br i1 undef, label %if, label %loopexit1 + +if: + br i1 undef, label %latch, label %loopexit2 + +latch: + br i1 undef, label %header, label %loopexit3 + +; CHECK: loopexit1: +; CHECK: %x.lcssa = phi i32 [ %x, %header ] +loopexit1: + br label %loop_with_insert_point + +; CHECK: loopexit2: +; CHECK: %x.lcssa1 = phi i32 [ %x, %if ] +loopexit2: + br label %exit + +; CHECK: loopexit3: +; CHECK: %x.lcssa2 = phi i32 [ %x, %latch ] +loopexit3: + br label %loop_with_insert_point + +; CHECK: loop_with_insert_point: +; CHECK: %x4 = phi i32 [ %x4, %loop_with_insert_point ], [ %x.lcssa2, %loopexit3 ], [ %x.lcssa, %loopexit1 ] +loop_with_insert_point: + br i1 undef, label %loop_with_insert_point, label %bb + +; CHECK: bb: +; CHECK: %x4.lcssa = phi i32 [ %x4, %loop_with_insert_point ] +bb: + br label %exit + +; CHECK: exit: +; CHECK: %x3 = phi i32 [ %x4.lcssa, %bb ], [ %x.lcssa1, %loopexit2 ] +exit: + ret i32 %x +} + +; CHECK-LABEL: @foo2 +define internal i32 @foo2() { +entry: + br label %header + +header: + %x = add i32 0, 1 + br i1 undef, label %latch, label %loopexit1 + +latch: + br i1 undef, label %header, label %loopexit2 + +; CHECK: loopexit1: +; CHECK: %x.lcssa = phi i32 [ %x, %header ] +loopexit1: + br label %loop_with_insert_point + +; CHECK: loopexit2: +; CHECK: %x.lcssa1 = phi i32 [ %x, %latch ] +loopexit2: + br label %loop_with_insert_point + +; CHECK: loop_with_insert_point: +; CHECK: %x2 = phi i32 [ %x2, %loop_with_insert_point ], [ %x.lcssa1, %loopexit2 ], [ %x.lcssa, %loopexit1 ] +loop_with_insert_point: + br i1 undef, label %loop_with_insert_point, label %exit + +; CHECK: exit: +; CHECK: %x2.lcssa = phi i32 [ %x2, %loop_with_insert_point ] +exit: + ret i32 %x +} diff --git a/test/Transforms/LCSSA/pr28608.ll b/test/Transforms/LCSSA/pr28608.ll new file mode 100644 index 000000000000..3ba3fe8cda11 --- /dev/null +++ b/test/Transforms/LCSSA/pr28608.ll @@ -0,0 +1,35 @@ +; RUN: opt < %s -lcssa -disable-output +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; PR28608 +; Check that we don't crash on this test. + +define void @foo() { +entry: + br label %bb1 + +bb1: + br label %bb2 + +bb2: + %x = phi i32 [ undef, %bb5 ], [ undef, %bb1 ] + br i1 undef, label %bb3, label %bb6 + +bb3: + br i1 undef, label %bb5, label %bb4 + +bb4: + br label %bb6 + +bb5: + br label %bb2 + +bb6: + br label %bb1 + +exit: + %y = add i32 0, %x + ret void +} + diff --git a/test/Transforms/LoopSimplify/pr28272.ll b/test/Transforms/LoopSimplify/pr28272.ll new file mode 100644 index 000000000000..49990f92cabe --- /dev/null +++ b/test/Transforms/LoopSimplify/pr28272.ll @@ -0,0 +1,76 @@ +; RUN: opt < %s -lcssa -loop-unroll -S | FileCheck %s +target triple = "x86_64-unknown-linux-gnu" + +; PR28272 +; When LoopSimplify separates nested loops, it might break LCSSA form: values +; from the original loop might be used in the outer loop. This test invokes +; loop-unroll, which calls loop-simplify before itself. If LCSSA is broken +; after loop-simplify, we crash on assertion. + +; CHECK-LABEL: @foo +define void @foo() { +entry: + br label %header + +header: + br label %loop1 + +loop1: + br i1 true, label %loop1, label %bb43 + +bb43: + %a = phi i32 [ undef, %loop1 ], [ 0, %bb45 ], [ %a, %bb54 ] + %b = phi i32 [ 0, %loop1 ], [ 1, %bb54 ], [ %c, %bb45 ] + br i1 true, label %bb114, label %header + +bb114: + %c = add i32 0, 1 + %d = add i32 0, 1 + br i1 true, label %bb45, label %bb54 + +bb45: + %x = add i32 %d, 0 + br label %bb43 + +bb54: + br label %bb43 +} + +; CHECK-LABEL: @foo2 +define void @foo2() { +entry: + br label %outer + +outer.loopexit: + br label %outer + +outer: + br label %loop1 + +loop1: + br i1 true, label %loop1, label %loop2.preheader + +loop2.preheader: + %a.ph = phi i32 [ undef, %loop1 ] + %b.ph = phi i32 [ 0, %loop1 ] + br label %loop2 + +loop2: + %a = phi i32 [ 0, %loop2.if.true ], [ %a, %loop2.if.false ], [ %a.ph, %loop2.preheader ], [0, %bb] + %b = phi i32 [ 1, %loop2.if.false ], [ %c, %loop2.if.true ], [ %b.ph, %loop2.preheader ], [%c, %bb] + br i1 true, label %loop2.if, label %outer.loopexit + +loop2.if: + %c = add i32 0, 1 + switch i32 undef, label %loop2.if.false [i32 0, label %loop2.if.true + i32 1, label %bb] + +loop2.if.true: + br i1 undef, label %loop2, label %bb + +loop2.if.false: + br label %loop2 + +bb: + br label %loop2 +} diff --git a/test/Transforms/LoopStrengthReduce/X86/pr28719.ll b/test/Transforms/LoopStrengthReduce/X86/pr28719.ll new file mode 100644 index 000000000000..0e74ff20073b --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/X86/pr28719.ll @@ -0,0 +1,47 @@ +; RUN: opt < %s -loop-reduce -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@a = global i32 0, align 4 +@b = global i8 0, align 1 +@c = global [4 x i8] zeroinitializer, align 1 + +; Just make sure we don't generate code with uses not dominated by defs. +; CHECK-LABEL: @main( +define i32 @main() { +entry: + %a0 = load i32, i32* @a, align 4 + %cmpa = icmp slt i32 %a0, 4 + br i1 %cmpa, label %preheader, label %for.end + +preheader: + %b0 = load i8, i8* @b, align 1 + %b0sext = sext i8 %b0 to i64 + br label %for.body + +for.body: + %iv = phi i64 [ 0, %preheader ], [ %iv.next, %lor.false ] + %mul = mul nsw i64 %b0sext, %iv + %multrunc = trunc i64 %mul to i32 + %cmp = icmp eq i32 %multrunc, 0 + br i1 %cmp, label %lor.false, label %if.then + +lor.false: + %cgep = getelementptr inbounds [4 x i8], [4 x i8]* @c, i64 0, i64 %iv + %ci = load i8, i8* %cgep, align 1 + %cisext = sext i8 %ci to i32 + %ivtrunc = trunc i64 %iv to i32 + %cmp2 = icmp eq i32 %cisext, %ivtrunc + %iv.next = add i64 %iv, 1 + br i1 %cmp2, label %for.body, label %if.then + +if.then: + tail call void @abort() + unreachable + +for.end: + ret i32 0 +} + +declare void @abort() diff --git a/test/Transforms/LoopVectorize/pr28541.ll b/test/Transforms/LoopVectorize/pr28541.ll new file mode 100644 index 000000000000..7bb7f0987fdf --- /dev/null +++ b/test/Transforms/LoopVectorize/pr28541.ll @@ -0,0 +1,71 @@ +; RUN: opt -loop-vectorize -pass-remarks=loop-vectorize -S < %s 2>&1 | FileCheck %s + +; FIXME: Check for -pass-remarks-missed and -pass-remarks-analysis output when +; addAcyclicInnerLoop emits analysis. + +; Check that opt does not crash on such input: +; +; a, b, c; +; fn1() { +; while (b--) { +; c = a; +; switch (a & 3) +; case 0: +; do +; case 3: +; case 2: +; case 1: +; ; +; while (--c) +; ; +; } +; } + +@b = common global i32 0, align 4 +@a = common global i32 0, align 4 +@c = common global i32 0, align 4 + +; CHECK-NOT: vectorized loop +; CHECK-LABEL: fn1 + +define i32 @fn1() { +entry: + %tmp2 = load i32, i32* @b, align 4 + %dec3 = add nsw i32 %tmp2, -1 + store i32 %dec3, i32* @b, align 4 + %tobool4 = icmp eq i32 %tmp2, 0 + br i1 %tobool4, label %while.end, label %while.body.lr.ph + +while.body.lr.ph: ; preds = %entry + %tmp1 = load i32, i32* @a, align 4 + %and = and i32 %tmp1, 3 + %switch = icmp eq i32 %and, 0 + br label %while.body + +while.cond: ; preds = %do.cond + %dec = add nsw i32 %dec7, -1 + %tobool = icmp eq i32 %dec7, 0 + br i1 %tobool, label %while.cond.while.end_crit_edge, label %while.body + +while.body: ; preds = %while.body.lr.ph, %while.cond + %dec7 = phi i32 [ %dec3, %while.body.lr.ph ], [ %dec, %while.cond ] + br i1 %switch, label %do.body, label %do.cond + +do.body: ; preds = %do.cond, %while.body + %dec25 = phi i32 [ %dec2, %do.cond ], [ %tmp1, %while.body ] + br label %do.cond + +do.cond: ; preds = %do.body, %while.body + %dec26 = phi i32 [ %dec25, %do.body ], [ %tmp1, %while.body ] + %dec2 = add nsw i32 %dec26, -1 + %tobool3 = icmp eq i32 %dec2, 0 + br i1 %tobool3, label %while.cond, label %do.body + +while.cond.while.end_crit_edge: ; preds = %while.cond + store i32 0, i32* @c, align 4 + store i32 -1, i32* @b, align 4 + br label %while.end + +while.end: ; preds = %while.cond.while.end_crit_edge, %entry + ret i32 undef +} diff --git a/test/Transforms/SafeStack/coloring-ssp.ll b/test/Transforms/SafeStack/coloring-ssp.ll new file mode 100644 index 000000000000..d71babe200df --- /dev/null +++ b/test/Transforms/SafeStack/coloring-ssp.ll @@ -0,0 +1,34 @@ +; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s + +; %x and %y share a stack slot between them, but not with the stack guard. +define void @f() safestack sspreq { +; CHECK-LABEL: define void @f +entry: +; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr +; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 + +; CHECK: %[[A:.*]] = getelementptr i8, i8* %[[USP]], i32 -8 +; CHECK: %[[StackGuardSlot:.*]] = bitcast i8* %[[A]] to i8** +; CHECK: store i8* %{{.*}}, i8** %[[StackGuardSlot]] + + %x = alloca i64, align 8 + %y = alloca i64, align 8 + %x0 = bitcast i64* %x to i8* + %y0 = bitcast i64* %y to i8* + + call void @llvm.lifetime.start(i64 -1, i8* %x0) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 + call void @capture64(i64* %x) + call void @llvm.lifetime.end(i64 -1, i8* %x0) + + call void @llvm.lifetime.start(i64 -1, i8* %y0) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 + call void @capture64(i64* %y) + call void @llvm.lifetime.end(i64 -1, i8* %y0) + + ret void +} + +declare void @llvm.lifetime.start(i64, i8* nocapture) +declare void @llvm.lifetime.end(i64, i8* nocapture) +declare void @capture64(i64*) diff --git a/test/Transforms/SafeStack/layout-region-split.ll b/test/Transforms/SafeStack/layout-region-split.ll new file mode 100644 index 000000000000..ceb18bb70c20 --- /dev/null +++ b/test/Transforms/SafeStack/layout-region-split.ll @@ -0,0 +1,84 @@ +; Regression test for safestack layout. Used to fail with asan. +; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s + +define void @f() safestack { +; CHECK-LABEL: define void @f +entry: +; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr +; CHECK: getelementptr i8, i8* %[[USP]], i32 -224 + + %x0 = alloca i8, align 16 + %x1 = alloca i8, align 16 + %x2 = alloca i8, align 16 + %x3 = alloca i8, align 16 + %x4 = alloca i8, align 16 + %x5 = alloca i8, align 16 + %x6 = alloca i8, align 16 + %x7 = alloca i8, align 16 + %x8 = alloca i8, align 16 + %x9 = alloca i8, align 16 + %x10 = alloca i8, align 16 + %x11 = alloca i8, align 16 + %x12 = alloca i8, align 16 + %x13 = alloca i8, align 16 + %y0 = alloca i8, align 2 + %y1 = alloca i8, align 2 + %y2 = alloca i8, align 2 + %y3 = alloca i8, align 2 + %y4 = alloca i8, align 2 + %y5 = alloca i8, align 2 + %y6 = alloca i8, align 2 + %y7 = alloca i8, align 2 + %y8 = alloca i8, align 2 + +; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 + call void @capture8(i8* %x0) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -32 + call void @capture8(i8* %x1) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -48 + call void @capture8(i8* %x2) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -64 + call void @capture8(i8* %x3) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -80 + call void @capture8(i8* %x4) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -96 + call void @capture8(i8* %x5) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -112 + call void @capture8(i8* %x6) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -128 + call void @capture8(i8* %x7) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -144 + call void @capture8(i8* %x8) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -160 + call void @capture8(i8* %x9) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -176 + call void @capture8(i8* %x10) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -192 + call void @capture8(i8* %x11) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -208 + call void @capture8(i8* %x12) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -224 + call void @capture8(i8* %x13) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -2 + call void @capture8(i8* %y0) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 + call void @capture8(i8* %y1) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -6 + call void @capture8(i8* %y2) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 + call void @capture8(i8* %y3) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -10 + call void @capture8(i8* %y4) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -12 + call void @capture8(i8* %y5) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -14 + call void @capture8(i8* %y6) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -18 + call void @capture8(i8* %y7) +; CHECK: getelementptr i8, i8* %[[USP]], i32 -20 + call void @capture8(i8* %y8) + + ret void +} + +declare void @capture8(i8*) |
