diff options
Diffstat (limited to 'test/Transforms')
-rw-r--r-- | test/Transforms/DeadStoreElimination/simple.ll | 14 | ||||
-rw-r--r-- | test/Transforms/GVN/malloc-load-removal.ll | 31 | ||||
-rw-r--r-- | test/Transforms/InstCombine/2012-08-28-udiv_ashl.ll | 57 | ||||
-rw-r--r-- | test/Transforms/InstCombine/fold-vector-select.ll | 153 | ||||
-rw-r--r-- | test/Transforms/InstCombine/udiv-simplify-bug-1.ll | 4 | ||||
-rw-r--r-- | test/Transforms/JumpThreading/select.ll | 36 | ||||
-rw-r--r-- | test/Transforms/LICM/hoisting.ll | 28 | ||||
-rw-r--r-- | test/Transforms/LoopRotate/multiple-exits.ll | 236 | ||||
-rw-r--r-- | test/Transforms/ObjCARC/basic.ll | 4 | ||||
-rw-r--r-- | test/Transforms/ObjCARC/nested.ll | 85 | ||||
-rw-r--r-- | test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll | 37 | ||||
-rw-r--r-- | test/Transforms/SimplifyCFG/switch_create.ll | 5 | ||||
-rw-r--r-- | test/Transforms/SimplifyCFG/switch_to_lookup_table.ll | 140 | ||||
-rw-r--r-- | test/Transforms/SimplifyLibCalls/double-float-shrink.ll | 333 | ||||
-rw-r--r-- | test/Transforms/SimplifyLibCalls/float-shrink-compare.ll | 179 |
15 files changed, 1318 insertions, 24 deletions
diff --git a/test/Transforms/DeadStoreElimination/simple.ll b/test/Transforms/DeadStoreElimination/simple.ll index 7a8cdd5..e0eb90a 100644 --- a/test/Transforms/DeadStoreElimination/simple.ll +++ b/test/Transforms/DeadStoreElimination/simple.ll @@ -310,3 +310,17 @@ define void @test24([2 x i32]* %a, i32 %b, i32 %c) nounwind { store i32 %c, i32* %4, align 4 ret void } + +; Check another case like PR13547 where strdup is not like malloc. +; CHECK: @test25 +; CHECK: load i8 +; CHECK: store i8 0 +; CHECK: store i8 %tmp +define i8* @test25(i8* %p) nounwind { + %p.4 = getelementptr i8* %p, i64 4 + %tmp = load i8* %p.4, align 1 + store i8 0, i8* %p.4, align 1 + %q = call i8* @strdup(i8* %p) nounwind optsize + store i8 %tmp, i8* %p.4, align 1 + ret i8* %q +} diff --git a/test/Transforms/GVN/malloc-load-removal.ll b/test/Transforms/GVN/malloc-load-removal.ll new file mode 100644 index 0000000..66b6929 --- /dev/null +++ b/test/Transforms/GVN/malloc-load-removal.ll @@ -0,0 +1,31 @@ +; RUN: opt -S -basicaa -gvn < %s | FileCheck %s +; RUN: opt -S -basicaa -gvn -disable-simplify-libcalls < %s | FileCheck %s -check-prefix=CHECK_NO_LIBCALLS +; PR13694 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.8.0" + +declare i8* @malloc(i64) nounwind + +define noalias i8* @test() nounwind uwtable ssp { +entry: + %call = tail call i8* @malloc(i64 100) nounwind + %0 = load i8* %call, align 1 + %tobool = icmp eq i8 %0, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + store i8 0, i8* %call, align 1 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret i8* %call + +; CHECK: @test +; CHECK-NOT: load +; CHECK-NOT: icmp + +; CHECK_NO_LIBCALLS: @test +; CHECK_NO_LIBCALLS: load +; CHECK_NO_LIBCALLS: icmp +} diff --git a/test/Transforms/InstCombine/2012-08-28-udiv_ashl.ll b/test/Transforms/InstCombine/2012-08-28-udiv_ashl.ll new file mode 100644 index 0000000..4efaf8c --- /dev/null +++ b/test/Transforms/InstCombine/2012-08-28-udiv_ashl.ll @@ -0,0 +1,57 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +; rdar://12182093 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.8.0" + +; CHECK: @udiv400 +; CHECK: udiv i32 %x, 400 +; CHECK: ret +define i32 @udiv400(i32 %x) { +entry: + %div = lshr i32 %x, 2 + %div1 = udiv i32 %div, 100 + ret i32 %div1 +} + + +; CHECK: @udiv400_no +; CHECK: ashr +; CHECK: div +; CHECK: ret +define i32 @udiv400_no(i32 %x) { +entry: + %div = ashr i32 %x, 2 + %div1 = udiv i32 %div, 100 + ret i32 %div1 +} + +; CHECK: @sdiv400_yes +; CHECK: udiv i32 %x, 400 +; CHECK: ret +define i32 @sdiv400_yes(i32 %x) { +entry: + %div = lshr i32 %x, 2 + ; The sign bits of both operands are zero (i.e. we can prove they are + ; unsigned inputs), turn this into a udiv. + ; Next, optimize this just like sdiv. + %div1 = sdiv i32 %div, 100 + ret i32 %div1 +} + + +; CHECK: @udiv_i80 +; CHECK: udiv i80 %x, 400 +; CHECK: ret +define i80 @udiv_i80(i80 %x) { + %div = lshr i80 %x, 2 + %div1 = udiv i80 %div, 100 + ret i80 %div1 +} + +define i32 @no_crash_notconst_udiv(i32 %x, i32 %notconst) { + %div = lshr i32 %x, %notconst + %div1 = udiv i32 %div, 100 + ret i32 %div1 +} diff --git a/test/Transforms/InstCombine/fold-vector-select.ll b/test/Transforms/InstCombine/fold-vector-select.ll index 3f22522..2cb970b 100644 --- a/test/Transforms/InstCombine/fold-vector-select.ll +++ b/test/Transforms/InstCombine/fold-vector-select.ll @@ -1,13 +1,148 @@ ; RUN: opt < %s -instcombine -S | not grep select -define void @foo(<4 x i32> *%A, <4 x i32> *%B, <4 x i32> *%C, <4 x i32> *%D) { - %r = select <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> <i32 1, i32 2, i32 3, i32 4>, <4 x i32> zeroinitializer - %g = select <4 x i1> <i1 false, i1 false, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 6, i32 9, i32 1> - %b = select <4 x i1> <i1 false, i1 true, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 7, i32 1, i32 4, i32 9> - %a = select <4 x i1> zeroinitializer, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 8, i32 5> - store <4 x i32> %r, <4 x i32>* %A - store <4 x i32> %g, <4 x i32>* %B - store <4 x i32> %b, <4 x i32>* %C - store <4 x i32> %a, <4 x i32>* %D +define void @foo(<4 x i32> *%A, <4 x i32> *%B, <4 x i32> *%C, <4 x i32> *%D, + <4 x i32> *%E, <4 x i32> *%F, <4 x i32> *%G, <4 x i32> *%H, + <4 x i32> *%I, <4 x i32> *%J, <4 x i32> *%K, <4 x i32> *%L, + <4 x i32> *%M, <4 x i32> *%N, <4 x i32> *%O, <4 x i32> *%P, + <4 x i32> *%Q, <4 x i32> *%R, <4 x i32> *%S, <4 x i32> *%T, + <4 x i32> *%U, <4 x i32> *%V, <4 x i32> *%W, <4 x i32> *%X, + <4 x i32> *%Y, <4 x i32> *%Z, <4 x i32> *%BA, <4 x i32> *%BB, + <4 x i32> *%BC, <4 x i32> *%BD, <4 x i32> *%BE, <4 x i32> *%BF, + <4 x i32> *%BG, <4 x i32> *%BH, <4 x i32> *%BI, <4 x i32> *%BJ, + <4 x i32> *%BK, <4 x i32> *%BL, <4 x i32> *%BM, <4 x i32> *%BN, + <4 x i32> *%BO, <4 x i32> *%BP, <4 x i32> *%BQ, <4 x i32> *%BR, + <4 x i32> *%BS, <4 x i32> *%BT, <4 x i32> *%BU, <4 x i32> *%BV, + <4 x i32> *%BW, <4 x i32> *%BX, <4 x i32> *%BY, <4 x i32> *%BZ, + <4 x i32> *%CA, <4 x i32> *%CB, <4 x i32> *%CC, <4 x i32> *%CD, + <4 x i32> *%CE, <4 x i32> *%CF, <4 x i32> *%CG, <4 x i32> *%CH, + <4 x i32> *%CI, <4 x i32> *%CJ, <4 x i32> *%CK, <4 x i32> *%CL) { + %a = select <4 x i1> <i1 false, i1 false, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 9, i32 87, i32 57, i32 8> + %b = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 44, i32 99, i32 49, i32 29> + %c = select <4 x i1> <i1 false, i1 true, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 15, i32 18, i32 53, i32 84> + %d = select <4 x i1> <i1 true, i1 true, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 29, i32 82, i32 45, i32 16> + %e = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 11, i32 15, i32 32, i32 99> + %f = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 19, i32 86, i32 29, i32 33> + %g = select <4 x i1> <i1 false, i1 true, i1 true, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 44, i32 10, i32 26, i32 45> + %h = select <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> zeroinitializer, <4 x i32> <i32 88, i32 70, i32 90, i32 48> + %i = select <4 x i1> <i1 false, i1 false, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 30, i32 53, i32 42, i32 12> + %j = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 46, i32 24, i32 93, i32 26> + %k = select <4 x i1> <i1 false, i1 true, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 33, i32 99, i32 15, i32 57> + %l = select <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 51, i32 60, i32 60, i32 50> + %m = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 50, i32 12, i32 7, i32 45> + %n = select <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 15, i32 65, i32 36, i32 36> + %o = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 54, i32 0, i32 17, i32 78> + %p = select <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> zeroinitializer, <4 x i32> <i32 56, i32 13, i32 64, i32 48> + %q = select <4 x i1> <i1 false, i1 false, i1 false, i1 false>, <4 x i32> <i32 52, i32 69, i32 88, i32 11>, <4 x i32> zeroinitializer + %r = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x i32> <i32 5, i32 87, i32 68, i32 14>, <4 x i32> zeroinitializer + %s = select <4 x i1> <i1 false, i1 true, i1 false, i1 false>, <4 x i32> <i32 47, i32 17, i32 66, i32 63>, <4 x i32> zeroinitializer + %t = select <4 x i1> <i1 true, i1 true, i1 false, i1 false>, <4 x i32> <i32 64, i32 25, i32 73, i32 81>, <4 x i32> zeroinitializer + %u = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x i32> <i32 51, i32 41, i32 61, i32 63>, <4 x i32> zeroinitializer + %v = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> <i32 39, i32 59, i32 17, i32 0>, <4 x i32> zeroinitializer + %w = select <4 x i1> <i1 false, i1 true, i1 true, i1 false>, <4 x i32> <i32 91, i32 99, i32 97, i32 29>, <4 x i32> zeroinitializer + %x = select <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> <i32 89, i32 45, i32 89, i32 10>, <4 x i32> zeroinitializer + %y = select <4 x i1> <i1 false, i1 false, i1 false, i1 true>, <4 x i32> <i32 25, i32 70, i32 21, i32 27>, <4 x i32> zeroinitializer + %z = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> <i32 40, i32 12, i32 27, i32 88>, <4 x i32> zeroinitializer + %ba = select <4 x i1> <i1 false, i1 true, i1 false, i1 true>, <4 x i32> <i32 36, i32 35, i32 90, i32 23>, <4 x i32> zeroinitializer + %bb = select <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x i32> <i32 83, i32 3, i32 64, i32 82>, <4 x i32> zeroinitializer + %bc = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x i32> <i32 15, i32 72, i32 2, i32 54>, <4 x i32> zeroinitializer + %bd = select <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x i32> <i32 32, i32 47, i32 100, i32 84>, <4 x i32> zeroinitializer + %be = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x i32> <i32 92, i32 57, i32 82, i32 1>, <4 x i32> zeroinitializer + %bf = select <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> <i32 42, i32 14, i32 22, i32 89>, <4 x i32> zeroinitializer + %bg = select <4 x i1> <i1 false, i1 false, i1 false, i1 false>, <4 x i32> <i32 33, i32 10, i32 67, i32 66>, <4 x i32> <i32 42, i32 91, i32 47, i32 40> + %bh = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x i32> <i32 8, i32 13, i32 48, i32 0>, <4 x i32> <i32 84, i32 66, i32 87, i32 84> + %bi = select <4 x i1> <i1 false, i1 true, i1 false, i1 false>, <4 x i32> <i32 85, i32 96, i32 1, i32 94>, <4 x i32> <i32 54, i32 57, i32 7, i32 92> + %bj = select <4 x i1> <i1 true, i1 true, i1 false, i1 false>, <4 x i32> <i32 55, i32 21, i32 92, i32 68>, <4 x i32> <i32 51, i32 61, i32 62, i32 39> + %bk = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x i32> <i32 42, i32 18, i32 77, i32 74>, <4 x i32> <i32 82, i32 33, i32 30, i32 7> + %bl = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> <i32 80, i32 92, i32 61, i32 84>, <4 x i32> <i32 43, i32 89, i32 92, i32 6> + %bm = select <4 x i1> <i1 false, i1 true, i1 true, i1 false>, <4 x i32> <i32 49, i32 14, i32 62, i32 62>, <4 x i32> <i32 35, i32 33, i32 92, i32 59> + %bn = select <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> <i32 3, i32 97, i32 49, i32 18>, <4 x i32> <i32 56, i32 64, i32 19, i32 75> + %bo = select <4 x i1> <i1 false, i1 false, i1 false, i1 true>, <4 x i32> <i32 91, i32 57, i32 0, i32 1>, <4 x i32> <i32 43, i32 63, i32 64, i32 11> + %bp = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> <i32 41, i32 65, i32 18, i32 11>, <4 x i32> <i32 86, i32 26, i32 31, i32 3> + %bq = select <4 x i1> <i1 false, i1 true, i1 false, i1 true>, <4 x i32> <i32 31, i32 46, i32 32, i32 68>, <4 x i32> <i32 100, i32 59, i32 62, i32 6> + %br = select <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x i32> <i32 76, i32 67, i32 87, i32 7>, <4 x i32> <i32 63, i32 48, i32 97, i32 24> + %bs = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x i32> <i32 83, i32 89, i32 19, i32 4>, <4 x i32> <i32 21, i32 2, i32 40, i32 21> + %bt = select <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x i32> <i32 45, i32 76, i32 81, i32 100>, <4 x i32> <i32 65, i32 26, i32 100, i32 46> + %bu = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x i32> <i32 16, i32 75, i32 31, i32 17>, <4 x i32> <i32 37, i32 66, i32 86, i32 65> + %bv = select <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> <i32 13, i32 25, i32 43, i32 59>, <4 x i32> <i32 82, i32 78, i32 60, i32 52> + %bw = select <4 x i1> <i1 false, i1 false, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %bx = select <4 x i1> <i1 true, i1 false, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %by = select <4 x i1> <i1 false, i1 true, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %bz = select <4 x i1> <i1 true, i1 true, i1 false, i1 false>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %ca = select <4 x i1> <i1 false, i1 false, i1 true, i1 false>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %cb = select <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %cc = select <4 x i1> <i1 false, i1 true, i1 true, i1 false>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %cd = select <4 x i1> <i1 true, i1 true, i1 true, i1 false>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %ce = select <4 x i1> <i1 false, i1 false, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %cf = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %cg = select <4 x i1> <i1 false, i1 true, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %ch = select <4 x i1> <i1 true, i1 true, i1 false, i1 true>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %ci = select <4 x i1> <i1 false, i1 false, i1 true, i1 true>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %cj = select <4 x i1> <i1 true, i1 false, i1 true, i1 true>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %ck = select <4 x i1> <i1 false, i1 true, i1 true, i1 true>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + %cl = select <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer + store <4 x i32> %a, <4 x i32>* %A + store <4 x i32> %b, <4 x i32>* %B + store <4 x i32> %c, <4 x i32>* %C + store <4 x i32> %d, <4 x i32>* %D + store <4 x i32> %e, <4 x i32>* %E + store <4 x i32> %f, <4 x i32>* %F + store <4 x i32> %g, <4 x i32>* %G + store <4 x i32> %h, <4 x i32>* %H + store <4 x i32> %i, <4 x i32>* %I + store <4 x i32> %j, <4 x i32>* %J + store <4 x i32> %k, <4 x i32>* %K + store <4 x i32> %l, <4 x i32>* %L + store <4 x i32> %m, <4 x i32>* %M + store <4 x i32> %n, <4 x i32>* %N + store <4 x i32> %o, <4 x i32>* %O + store <4 x i32> %p, <4 x i32>* %P + store <4 x i32> %q, <4 x i32>* %Q + store <4 x i32> %r, <4 x i32>* %R + store <4 x i32> %s, <4 x i32>* %S + store <4 x i32> %t, <4 x i32>* %T + store <4 x i32> %u, <4 x i32>* %U + store <4 x i32> %v, <4 x i32>* %V + store <4 x i32> %w, <4 x i32>* %W + store <4 x i32> %x, <4 x i32>* %X + store <4 x i32> %y, <4 x i32>* %Y + store <4 x i32> %z, <4 x i32>* %Z + store <4 x i32> %ba, <4 x i32>* %BA + store <4 x i32> %bb, <4 x i32>* %BB + store <4 x i32> %bc, <4 x i32>* %BC + store <4 x i32> %bd, <4 x i32>* %BD + store <4 x i32> %be, <4 x i32>* %BE + store <4 x i32> %bf, <4 x i32>* %BF + store <4 x i32> %bg, <4 x i32>* %BG + store <4 x i32> %bh, <4 x i32>* %BH + store <4 x i32> %bi, <4 x i32>* %BI + store <4 x i32> %bj, <4 x i32>* %BJ + store <4 x i32> %bk, <4 x i32>* %BK + store <4 x i32> %bl, <4 x i32>* %BL + store <4 x i32> %bm, <4 x i32>* %BM + store <4 x i32> %bn, <4 x i32>* %BN + store <4 x i32> %bo, <4 x i32>* %BO + store <4 x i32> %bp, <4 x i32>* %BP + store <4 x i32> %bq, <4 x i32>* %BQ + store <4 x i32> %br, <4 x i32>* %BR + store <4 x i32> %bs, <4 x i32>* %BS + store <4 x i32> %bt, <4 x i32>* %BT + store <4 x i32> %bu, <4 x i32>* %BU + store <4 x i32> %bv, <4 x i32>* %BV + store <4 x i32> %bw, <4 x i32>* %BW + store <4 x i32> %bx, <4 x i32>* %BX + store <4 x i32> %by, <4 x i32>* %BY + store <4 x i32> %bz, <4 x i32>* %BZ + store <4 x i32> %ca, <4 x i32>* %CA + store <4 x i32> %cb, <4 x i32>* %CB + store <4 x i32> %cc, <4 x i32>* %CC + store <4 x i32> %cd, <4 x i32>* %CD + store <4 x i32> %ce, <4 x i32>* %CE + store <4 x i32> %cf, <4 x i32>* %CF + store <4 x i32> %cg, <4 x i32>* %CG + store <4 x i32> %ch, <4 x i32>* %CH + store <4 x i32> %ci, <4 x i32>* %CI + store <4 x i32> %cj, <4 x i32>* %CJ + store <4 x i32> %ck, <4 x i32>* %CK + store <4 x i32> %cl, <4 x i32>* %CL ret void } diff --git a/test/Transforms/InstCombine/udiv-simplify-bug-1.ll b/test/Transforms/InstCombine/udiv-simplify-bug-1.ll index d95e8f8..74f2fdd 100644 --- a/test/Transforms/InstCombine/udiv-simplify-bug-1.ll +++ b/test/Transforms/InstCombine/udiv-simplify-bug-1.ll @@ -6,9 +6,9 @@ ; The udiv instructions shouldn't be optimized away, and the ; sext instructions should be optimized to zext. -define i64 @bar(i32 %x) nounwind { +define i64 @bar(i32 %x, i32 %g) nounwind { %y = lshr i32 %x, 30 - %r = udiv i32 %y, 3 + %r = udiv i32 %y, %g %z = sext i32 %r to i64 ret i64 %z } diff --git a/test/Transforms/JumpThreading/select.ll b/test/Transforms/JumpThreading/select.ll index 8a81857..9676efe 100644 --- a/test/Transforms/JumpThreading/select.ll +++ b/test/Transforms/JumpThreading/select.ll @@ -121,3 +121,39 @@ L4: call void @quux() br label %L0 } + +; Make sure the edge value of %0 from entry to L2 includes 0 and L3 is +; reachable. +; CHECK: test_switch_default +; CHECK: entry: +; CHECK: load +; CHECK: switch +; CHECK: [[THREADED:[A-Za-z.0-9]+]]: +; CHECK: store +; CHECK: br +; CHECK: L2: +; CHECK: icmp +define void @test_switch_default(i32* nocapture %status) nounwind { +entry: + %0 = load i32* %status, align 4 + switch i32 %0, label %L2 [ + i32 5061, label %L1 + i32 0, label %L2 + ] + +L1: + store i32 10025, i32* %status, align 4 + br label %L2 + +L2: + %1 = load i32* %status, align 4 + %cmp57.i = icmp eq i32 %1, 0 + br i1 %cmp57.i, label %L3, label %L4 + +L3: + store i32 10000, i32* %status, align 4 + br label %L4 + +L4: + ret void +} diff --git a/test/Transforms/LICM/hoisting.ll b/test/Transforms/LICM/hoisting.ll index 6f28d53..98f9334 100644 --- a/test/Transforms/LICM/hoisting.ll +++ b/test/Transforms/LICM/hoisting.ll @@ -29,7 +29,7 @@ Out: ; preds = %LoopTail } -declare void @foo2(i32) +declare void @foo2(i32) nounwind ;; It is ok and desirable to hoist this potentially trapping instruction. @@ -64,3 +64,29 @@ Out: ; preds = %Loop %C = sub i32 %A, %B ; <i32> [#uses=1] ret i32 %C } + +; CHECK: @test4 +; CHECK: call +; CHECK: sdiv +; CHECK: ret +define i32 @test4(i32 %x, i32 %y) nounwind uwtable ssp { +entry: + br label %for.body + +for.body: ; preds = %entry, %for.body + %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %n.01 = phi i32 [ 0, %entry ], [ %add, %for.body ] + call void @foo_may_call_exit(i32 0) + %div = sdiv i32 %x, %y + %add = add nsw i32 %n.01, %div + %inc = add nsw i32 %i.02, 1 + %cmp = icmp slt i32 %inc, 10000 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.body + %n.0.lcssa = phi i32 [ %add, %for.body ] + ret i32 %n.0.lcssa +} + +declare void @foo_may_call_exit(i32) + diff --git a/test/Transforms/LoopRotate/multiple-exits.ll b/test/Transforms/LoopRotate/multiple-exits.ll new file mode 100644 index 0000000..675d71f --- /dev/null +++ b/test/Transforms/LoopRotate/multiple-exits.ll @@ -0,0 +1,236 @@ +; RUN: opt -S -loop-rotate < %s -verify-loop-info -verify-dom-info | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.8.0" + +; PR7447 +define i32 @test1([100 x i32]* nocapture %a) nounwind readonly { +entry: + br label %for.cond + +for.cond: ; preds = %for.cond1, %entry + %sum.0 = phi i32 [ 0, %entry ], [ %sum.1, %for.cond1 ] + %i.0 = phi i1 [ true, %entry ], [ false, %for.cond1 ] + br i1 %i.0, label %for.cond1, label %return + +for.cond1: ; preds = %for.cond, %land.rhs + %sum.1 = phi i32 [ %add, %land.rhs ], [ %sum.0, %for.cond ] + %i.1 = phi i32 [ %inc, %land.rhs ], [ 0, %for.cond ] + %cmp2 = icmp ult i32 %i.1, 100 + br i1 %cmp2, label %land.rhs, label %for.cond + +land.rhs: ; preds = %for.cond1 + %conv = zext i32 %i.1 to i64 + %arrayidx = getelementptr inbounds [100 x i32]* %a, i64 0, i64 %conv + %0 = load i32* %arrayidx, align 4 + %add = add i32 %0, %sum.1 + %cmp4 = icmp ugt i32 %add, 1000 + %inc = add i32 %i.1, 1 + br i1 %cmp4, label %return, label %for.cond1 + +return: ; preds = %for.cond, %land.rhs + %retval.0 = phi i32 [ 1000, %land.rhs ], [ %sum.0, %for.cond ] + ret i32 %retval.0 + +; CHECK: @test1 +; CHECK: for.cond1.preheader: +; CHECK: %sum.04 = phi i32 [ 0, %entry ], [ %sum.1.lcssa, %for.cond.loopexit ] +; CHECK: br label %for.cond1 + +; CHECK: for.cond1: +; CHECK: %sum.1 = phi i32 [ %add, %land.rhs ], [ %sum.04, %for.cond1.preheader ] +; CHECK: %i.1 = phi i32 [ %inc, %land.rhs ], [ 0, %for.cond1.preheader ] +; CHECK: %cmp2 = icmp ult i32 %i.1, 100 +; CHECK: br i1 %cmp2, label %land.rhs, label %for.cond.loopexit +} + +define void @test2(i32 %x) nounwind { +entry: + br label %for.cond + +for.cond: ; preds = %if.end, %entry + %i.0 = phi i32 [ 0, %entry ], [ %inc, %if.end ] + %cmp = icmp eq i32 %i.0, %x + br i1 %cmp, label %return.loopexit, label %for.body + +for.body: ; preds = %for.cond + %call = tail call i32 @foo(i32 %i.0) nounwind + %tobool = icmp eq i32 %call, 0 + br i1 %tobool, label %if.end, label %a + +if.end: ; preds = %for.body + %call1 = tail call i32 @foo(i32 42) nounwind + %inc = add i32 %i.0, 1 + br label %for.cond + +a: ; preds = %for.body + %call2 = tail call i32 @bar(i32 1) nounwind + br label %return + +return.loopexit: ; preds = %for.cond + br label %return + +return: ; preds = %return.loopexit, %a + ret void + +; CHECK: @test2 +; CHECK: if.end: +; CHECK: %inc = add i32 %i.02, 1 +; CHECK: %cmp = icmp eq i32 %inc, %x +; CHECK: br i1 %cmp, label %for.cond.return.loopexit_crit_edge, label %for.body +} + +declare i32 @foo(i32) + +declare i32 @bar(i32) + +@_ZTIi = external constant i8* + +; Verify dominators. +define void @test3(i32 %x) { +entry: + %cmp2 = icmp eq i32 0, %x + br i1 %cmp2, label %try.cont.loopexit, label %for.body.lr.ph + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.lr.ph, %for.inc + %i.03 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] + invoke void @_Z3fooi(i32 %i.03) + to label %for.inc unwind label %lpad + +for.inc: ; preds = %for.body + %inc = add i32 %i.03, 1 + %cmp = icmp eq i32 %inc, %x + br i1 %cmp, label %for.cond.try.cont.loopexit_crit_edge, label %for.body + +lpad: ; preds = %for.body + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast (i8** @_ZTIi to i8*) + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = extractvalue { i8*, i32 } %0, 1 + %3 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind + %matches = icmp eq i32 %2, %3 + br i1 %matches, label %catch, label %eh.resume + +catch: ; preds = %lpad + %4 = tail call i8* @__cxa_begin_catch(i8* %1) nounwind + br i1 true, label %invoke.cont2.loopexit, label %for.body.i.lr.ph + +for.body.i.lr.ph: ; preds = %catch + br label %for.body.i + +for.body.i: ; preds = %for.body.i.lr.ph, %for.inc.i + %i.0.i1 = phi i32 [ 0, %for.body.i.lr.ph ], [ %inc.i, %for.inc.i ] + invoke void @_Z3fooi(i32 %i.0.i1) + to label %for.inc.i unwind label %lpad.i + +for.inc.i: ; preds = %for.body.i + %inc.i = add i32 %i.0.i1, 1 + %cmp.i = icmp eq i32 %inc.i, 0 + br i1 %cmp.i, label %for.cond.i.invoke.cont2.loopexit_crit_edge, label %for.body.i + +lpad.i: ; preds = %for.body.i + %5 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast (i8** @_ZTIi to i8*) + %6 = extractvalue { i8*, i32 } %5, 0 + %7 = extractvalue { i8*, i32 } %5, 1 + %matches.i = icmp eq i32 %7, %3 + br i1 %matches.i, label %catch.i, label %lpad1.body + +catch.i: ; preds = %lpad.i + %8 = tail call i8* @__cxa_begin_catch(i8* %6) nounwind + invoke void @test3(i32 0) + to label %invoke.cont2.i unwind label %lpad1.i + +invoke.cont2.i: ; preds = %catch.i + tail call void @__cxa_end_catch() nounwind + br label %invoke.cont2 + +lpad1.i: ; preds = %catch.i + %9 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + %10 = extractvalue { i8*, i32 } %9, 0 + %11 = extractvalue { i8*, i32 } %9, 1 + tail call void @__cxa_end_catch() nounwind + br label %lpad1.body + +for.cond.i.invoke.cont2.loopexit_crit_edge: ; preds = %for.inc.i + br label %invoke.cont2.loopexit + +invoke.cont2.loopexit: ; preds = %for.cond.i.invoke.cont2.loopexit_crit_edge, %catch + br label %invoke.cont2 + +invoke.cont2: ; preds = %invoke.cont2.loopexit, %invoke.cont2.i + tail call void @__cxa_end_catch() nounwind + br label %try.cont + +for.cond.try.cont.loopexit_crit_edge: ; preds = %for.inc + br label %try.cont.loopexit + +try.cont.loopexit: ; preds = %for.cond.try.cont.loopexit_crit_edge, %entry + br label %try.cont + +try.cont: ; preds = %try.cont.loopexit, %invoke.cont2 + ret void + +lpad1.body: ; preds = %lpad1.i, %lpad.i + %exn.slot.0.i = phi i8* [ %10, %lpad1.i ], [ %6, %lpad.i ] + %ehselector.slot.0.i = phi i32 [ %11, %lpad1.i ], [ %7, %lpad.i ] + tail call void @__cxa_end_catch() nounwind + br label %eh.resume + +eh.resume: ; preds = %lpad1.body, %lpad + %exn.slot.0 = phi i8* [ %exn.slot.0.i, %lpad1.body ], [ %1, %lpad ] + %ehselector.slot.0 = phi i32 [ %ehselector.slot.0.i, %lpad1.body ], [ %2, %lpad ] + %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn.slot.0, 0 + %lpad.val5 = insertvalue { i8*, i32 } %lpad.val, i32 %ehselector.slot.0, 1 + resume { i8*, i32 } %lpad.val5 +} + +declare void @_Z3fooi(i32) + +declare i32 @__gxx_personality_v0(...) + +declare i32 @llvm.eh.typeid.for(i8*) nounwind readnone + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch() + +define void @test4() nounwind uwtable { +entry: + br label %"7" + +"3": ; preds = %"7" + br i1 undef, label %"31", label %"4" + +"4": ; preds = %"3" + %. = select i1 undef, float 0x3F50624DE0000000, float undef + %0 = add i32 %1, 1 + br label %"7" + +"7": ; preds = %"4", %entry + %1 = phi i32 [ %0, %"4" ], [ 0, %entry ] + %2 = icmp slt i32 %1, 100 + br i1 %2, label %"3", label %"8" + +"8": ; preds = %"7" + br i1 undef, label %"9", label %"31" + +"9": ; preds = %"8" + br label %"33" + +"27": ; preds = %"31" + unreachable + +"31": ; preds = %"8", %"3" + br i1 undef, label %"27", label %"32" + +"32": ; preds = %"31" + br label %"33" + +"33": ; preds = %"32", %"9" + ret void +} diff --git a/test/Transforms/ObjCARC/basic.ll b/test/Transforms/ObjCARC/basic.ll index 0a7ba5d..7b64b1b 100644 --- a/test/Transforms/ObjCARC/basic.ll +++ b/test/Transforms/ObjCARC/basic.ll @@ -1,4 +1,4 @@ -; RUN: opt -objc-arc -S < %s | FileCheck %s +; RUN: opt -basicaa -objc-arc -S < %s | FileCheck %s target datalayout = "e-p:64:64:64" @@ -1498,7 +1498,7 @@ define i8* @test49(i8* %p) nounwind { } ; Do delete retain+release with intervening stores of the -; address value; +; address value. ; CHECK: define void @test50( ; CHECK-NOT: @objc_ diff --git a/test/Transforms/ObjCARC/nested.ll b/test/Transforms/ObjCARC/nested.ll index a618a21..32be03e 100644 --- a/test/Transforms/ObjCARC/nested.ll +++ b/test/Transforms/ObjCARC/nested.ll @@ -16,6 +16,10 @@ declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind declare void @use(i8*) declare void @objc_release(i8*) +declare i8* @def() +declare void @__crasher_block_invoke(i8* nocapture) +declare i8* @objc_retainBlock(i8*) +declare void @__crasher_block_invoke1(i8* nocapture) !0 = metadata !{} @@ -279,11 +283,13 @@ forcoll.empty: ret void } -; Delete a nested retain+release pair. +; TODO: Delete a nested retain+release pair. +; The optimizer currently can't do this, because isn't isn't sophisticated enough in +; reasnoning about nesting. ; CHECK: define void @test6( ; CHECK: call i8* @objc_retain -; CHECK-NOT: @objc_retain +; CHECK: @objc_retain ; CHECK: } define void @test6() nounwind { entry: @@ -345,11 +351,13 @@ forcoll.empty: ret void } -; Delete a nested retain+release pair. +; TODO: Delete a nested retain+release pair. +; The optimizer currently can't do this, because isn't isn't sophisticated enough in +; reasnoning about nesting. ; CHECK: define void @test7( ; CHECK: call i8* @objc_retain -; CHECK-NOT: @objc_retain +; CHECK: @objc_retain ; CHECK: } define void @test7() nounwind { entry: @@ -553,12 +561,12 @@ forcoll.empty: ret void } -; Like test9, but without a split backedge. This we can optimize. +; Like test9, but without a split backedge. TODO: optimize this. ; CHECK: define void @test9b( ; CHECK: call i8* @objc_retain ; CHECK: call i8* @objc_retain -; CHECK-NOT: @objc_retain +; CHECK: @objc_retain ; CHECK: } define void @test9b() nounwind { entry: @@ -687,12 +695,12 @@ forcoll.empty: ret void } -; Like test10, but without a split backedge. This we can optimize. +; Like test10, but without a split backedge. TODO: optimize this. ; CHECK: define void @test10b( ; CHECK: call i8* @objc_retain ; CHECK: call i8* @objc_retain -; CHECK-NOT: @objc_retain +; CHECK: @objc_retain ; CHECK: } define void @test10b() nounwind { entry: @@ -751,3 +759,64 @@ forcoll.empty: call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0 ret void } + +; Pointers to strong pointers can obscure provenance relationships. Be conservative +; in the face of escaping pointers. rdar://12150909. + +%struct.__block_d = type { i64, i64 } + +@_NSConcreteStackBlock = external global i8* +@__block_d_tmp = external hidden constant { i64, i64, i8*, i8*, i8*, i8* } +@__block_d_tmp5 = external hidden constant { i64, i64, i8*, i8*, i8*, i8* } + +; CHECK: define void @test11( +; CHECK: tail call i8* @objc_retain(i8* %call) nounwind +; CHECK: tail call i8* @objc_retain(i8* %call) nounwind +; CHECK: call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0 +; CHECK: } +define void @test11() { +entry: + %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>, align 8 + %block9 = alloca <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>, align 8 + %call = call i8* @def(), !clang.arc.no_objc_arc_exceptions !0 + %foo = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block, i64 0, i32 5 + %block.isa = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block, i64 0, i32 0 + store i8* bitcast (i8** @_NSConcreteStackBlock to i8*), i8** %block.isa, align 8 + %block.flags = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block, i64 0, i32 1 + store i32 1107296256, i32* %block.flags, align 8 + %block.reserved = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block, i64 0, i32 2 + store i32 0, i32* %block.reserved, align 4 + %block.invoke = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block, i64 0, i32 3 + store i8* bitcast (void (i8*)* @__crasher_block_invoke to i8*), i8** %block.invoke, align 8 + %block.d = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block, i64 0, i32 4 + store %struct.__block_d* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @__block_d_tmp to %struct.__block_d*), %struct.__block_d** %block.d, align 8 + %foo2 = tail call i8* @objc_retain(i8* %call) nounwind + store i8* %foo2, i8** %foo, align 8 + %foo4 = bitcast <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block to i8* + %foo5 = call i8* @objc_retainBlock(i8* %foo4) nounwind + call void @use(i8* %foo5), !clang.arc.no_objc_arc_exceptions !0 + call void @objc_release(i8* %foo5) nounwind + %strongdestroy = load i8** %foo, align 8 + call void @objc_release(i8* %strongdestroy) nounwind, !clang.imprecise_release !0 + %foo10 = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block9, i64 0, i32 5 + %block.isa11 = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block9, i64 0, i32 0 + store i8* bitcast (i8** @_NSConcreteStackBlock to i8*), i8** %block.isa11, align 8 + %block.flags12 = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block9, i64 0, i32 1 + store i32 1107296256, i32* %block.flags12, align 8 + %block.reserved13 = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block9, i64 0, i32 2 + store i32 0, i32* %block.reserved13, align 4 + %block.invoke14 = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block9, i64 0, i32 3 + store i8* bitcast (void (i8*)* @__crasher_block_invoke1 to i8*), i8** %block.invoke14, align 8 + %block.d15 = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block9, i64 0, i32 4 + store %struct.__block_d* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @__block_d_tmp5 to %struct.__block_d*), %struct.__block_d** %block.d15, align 8 + %foo18 = call i8* @objc_retain(i8* %call) nounwind + store i8* %call, i8** %foo10, align 8 + %foo20 = bitcast <{ i8*, i32, i32, i8*, %struct.__block_d*, i8* }>* %block9 to i8* + %foo21 = call i8* @objc_retainBlock(i8* %foo20) nounwind + call void @use(i8* %foo21), !clang.arc.no_objc_arc_exceptions !0 + call void @objc_release(i8* %foo21) nounwind + %strongdestroy25 = load i8** %foo10, align 8 + call void @objc_release(i8* %strongdestroy25) nounwind, !clang.imprecise_release !0 + call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0 + ret void +} diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll b/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll new file mode 100644 index 0000000..53d5448 --- /dev/null +++ b/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll @@ -0,0 +1,37 @@ +; RUN: opt -simplifycfg -S -o - < %s | FileCheck %s + +; This test case was written to trigger an incorrect assert statement in +; -simplifycfg. Thus we don't actually want to check the output, just that +; -simplifycfg ran successfully. Thus we only check that the function still +; exists, and that it still calls foo(). +; +; NOTE: There are some obviously dead blocks and missing branch weight +; metadata. Both of these features were key to triggering the assert. +; Additionally, the not-taken weight of the branch with a weight had to +; be 0 to trigger the assert. + +declare void @foo() nounwind uwtable + +define void @func(i32 %A) nounwind uwtable { +; CHECK: define void @func +entry: + %cmp11 = icmp eq i32 %A, 1 + br i1 %cmp11, label %if.then, label %if.else, !prof !0 + +if.then: + call void @foo() +; CHECK: call void @foo() + br label %if.else + +if.else: + %cmp17 = icmp eq i32 %A, 2 + br i1 %cmp17, label %if.then2, label %if.end + +if.then2: + br label %if.end + +if.end: + ret void +} + +!0 = metadata !{metadata !"branch_weights", i32 1, i32 0} diff --git a/test/Transforms/SimplifyCFG/switch_create.ll b/test/Transforms/SimplifyCFG/switch_create.ll index 546cc75..b28e4a4 100644 --- a/test/Transforms/SimplifyCFG/switch_create.ll +++ b/test/Transforms/SimplifyCFG/switch_create.ll @@ -141,8 +141,9 @@ UnifiedReturnBlock: ; preds = %shortcirc_done.4, %shortcirc_next.4 ret i1 %UnifiedRetVal ; CHECK: @test6 -; CHECK: %tmp.2.i.off = add i32 %tmp.2.i, -14 -; CHECK: %switch = icmp ult i32 %tmp.2.i.off, 6 +; CHECK: %switch.tableidx = sub i32 %tmp.2.i, 14 +; CHECK: %0 = icmp ult i32 %switch.tableidx, 6 +; CHECK: select i1 %0, i1 true, i1 false } define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone { diff --git a/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll b/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll new file mode 100644 index 0000000..414da93 --- /dev/null +++ b/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll @@ -0,0 +1,140 @@ +; RUN: opt < %s -simplifycfg -S | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; The table for @f +; CHECK: @switch.table = private unnamed_addr constant [7 x i32] [i32 55, i32 123, i32 0, i32 -1, i32 27, i32 62, i32 1] + +; The int table for @h +; CHECK: @switch.table1 = private unnamed_addr constant [4 x i8] c"*\09X\05" + +; The float table for @h +; CHECK: @switch.table2 = private unnamed_addr constant [4 x float] [float 0x40091EB860000000, float 0x3FF3BE76C0000000, float 0x4012449BA0000000, float 0x4001AE1480000000] + +; The table for @foostring +; CHECK: @switch.table3 = private unnamed_addr constant [4 x i8*] [i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str1, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str2, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str3, i64 0, i64 0)] + +; A simple int-to-int selection switch. +; It is dense enough to be replaced by table lookup. +; The result is directly by a ret from an otherwise empty bb, +; so we return early, directly from the lookup bb. + +define i32 @f(i32 %c) nounwind uwtable readnone { +entry: + switch i32 %c, label %sw.default [ + i32 42, label %return + i32 43, label %sw.bb1 + i32 44, label %sw.bb2 + i32 45, label %sw.bb3 + i32 46, label %sw.bb4 + i32 47, label %sw.bb5 + i32 48, label %sw.bb6 + ] + +sw.bb1: br label %return +sw.bb2: br label %return +sw.bb3: br label %return +sw.bb4: br label %return +sw.bb5: br label %return +sw.bb6: br label %return +sw.default: br label %return +return: + %retval.0 = phi i32 [ 15, %sw.default ], [ 1, %sw.bb6 ], [ 62, %sw.bb5 ], [ 27, %sw.bb4 ], [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ] + ret i32 %retval.0 + +; CHECK: @f +; CHECK: entry: +; CHECK-NEXT: %switch.tableidx = sub i32 %c, 42 +; CHECK-NEXT: %0 = icmp ult i32 %switch.tableidx, 7 +; CHECK-NEXT: br i1 %0, label %switch.lookup, label %return +; CHECK: switch.lookup: +; CHECK-NEXT: %switch.gep = getelementptr inbounds [7 x i32]* @switch.table, i32 0, i32 %switch.tableidx +; CHECK-NEXT: %switch.load = load i32* %switch.gep +; CHECK-NEXT: ret i32 %switch.load +; CHECK: return: +; CHECK-NEXT: ret i32 15 +} + +; A switch used to initialize two variables, an i8 and a float. + +declare void @dummy(i8 signext, float) +define void @h(i32 %x) { +entry: + switch i32 %x, label %sw.default [ + i32 0, label %sw.epilog + i32 1, label %sw.bb1 + i32 2, label %sw.bb2 + i32 3, label %sw.bb3 + ] + +sw.bb1: br label %sw.epilog +sw.bb2: br label %sw.epilog +sw.bb3: br label %sw.epilog +sw.default: br label %sw.epilog + +sw.epilog: + %a.0 = phi i8 [ 7, %sw.default ], [ 5, %sw.bb3 ], [ 88, %sw.bb2 ], [ 9, %sw.bb1 ], [ 42, %entry ] + %b.0 = phi float [ 0x4023FAE140000000, %sw.default ], [ 0x4001AE1480000000, %sw.bb3 ], [ 0x4012449BA0000000, %sw.bb2 ], [ 0x3FF3BE76C0000000, %sw.bb1 ], [ 0x40091EB860000000, %entry ] + call void @dummy(i8 signext %a.0, float %b.0) + ret void + +; CHECK: @h +; CHECK: entry: +; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0 +; CHECK-NEXT: %0 = icmp ult i32 %switch.tableidx, 4 +; CHECK-NEXT: br i1 %0, label %switch.lookup, label %sw.epilog +; CHECK: switch.lookup: +; CHECK-NEXT: %switch.gep = getelementptr inbounds [4 x i8]* @switch.table1, i32 0, i32 %switch.tableidx +; CHECK-NEXT: %switch.load = load i8* %switch.gep +; CHECK-NEXT: %switch.gep1 = getelementptr inbounds [4 x float]* @switch.table2, i32 0, i32 %switch.tableidx +; CHECK-NEXT: %switch.load2 = load float* %switch.gep1 +; CHECK-NEXT: br label %sw.epilog +; CHECK: sw.epilog: +; CHECK-NEXT: %a.0 = phi i8 [ %switch.load, %switch.lookup ], [ 7, %entry ] +; CHECK-NEXT: %b.0 = phi float [ %switch.load2, %switch.lookup ], [ 0x4023FAE140000000, %entry ] +; CHECK-NEXT: call void @dummy(i8 signext %a.0, float %b.0) +; CHECK-NEXT: ret void +} + + +; Switch used to return a string. + +@.str = private unnamed_addr constant [4 x i8] c"foo\00", align 1 +@.str1 = private unnamed_addr constant [4 x i8] c"bar\00", align 1 +@.str2 = private unnamed_addr constant [4 x i8] c"baz\00", align 1 +@.str3 = private unnamed_addr constant [4 x i8] c"qux\00", align 1 +@.str4 = private unnamed_addr constant [6 x i8] c"error\00", align 1 + +define i8* @foostring(i32 %x) { +entry: + switch i32 %x, label %sw.default [ + i32 0, label %return + i32 1, label %sw.bb1 + i32 2, label %sw.bb2 + i32 3, label %sw.bb3 + ] + +sw.bb1: br label %return +sw.bb2: br label %return +sw.bb3: br label %return +sw.default: br label %return + +return: + %retval.0 = phi i8* [ getelementptr inbounds ([6 x i8]* @.str4, i64 0, i64 0), %sw.default ], + [ getelementptr inbounds ([4 x i8]* @.str3, i64 0, i64 0), %sw.bb3 ], + [ getelementptr inbounds ([4 x i8]* @.str2, i64 0, i64 0), %sw.bb2 ], + [ getelementptr inbounds ([4 x i8]* @.str1, i64 0, i64 0), %sw.bb1 ], + [ getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), %entry ] + ret i8* %retval.0 + +; CHECK: @foostring +; CHECK: entry: +; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0 +; CHECK-NEXT: %0 = icmp ult i32 %switch.tableidx, 4 +; CHECK-NEXT: br i1 %0, label %switch.lookup, label %return +; CHECK: switch.lookup: +; CHECK-NEXT: %switch.gep = getelementptr inbounds [4 x i8*]* @switch.table3, i32 0, i32 %switch.tableidx +; CHECK-NEXT: %switch.load = load i8** %switch.gep +; CHECK-NEXT: ret i8* %switch.load +} diff --git a/test/Transforms/SimplifyLibCalls/double-float-shrink.ll b/test/Transforms/SimplifyLibCalls/double-float-shrink.ll new file mode 100644 index 0000000..b4ab8b4 --- /dev/null +++ b/test/Transforms/SimplifyLibCalls/double-float-shrink.ll @@ -0,0 +1,333 @@ +; RUN: opt < %s -simplify-libcalls -enable-double-float-shrink -S | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define float @acos_test(float %f) nounwind readnone { +; CHECK: acos_test + %conv = fpext float %f to double + %call = call double @acos(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @acosf(float %f) +} + +define double @acos_test2(float %f) nounwind readnone { +; CHECK: acos_test2 + %conv = fpext float %f to double + %call = call double @acos(double %conv) + ret double %call +; CHECK: call double @acos(double %conv) +} + +define float @acosh_test(float %f) nounwind readnone { +; CHECK: acosh_test + %conv = fpext float %f to double + %call = call double @acosh(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @acoshf(float %f) +} + +define double @acosh_test2(float %f) nounwind readnone { +; CHECK: acosh_test2 + %conv = fpext float %f to double + %call = call double @acosh(double %conv) + ret double %call +; CHECK: call double @acosh(double %conv) +} + +define float @asin_test(float %f) nounwind readnone { +; CHECK: asin_test + %conv = fpext float %f to double + %call = call double @asin(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @asinf(float %f) +} + +define double @asin_test2(float %f) nounwind readnone { +; CHECK: asin_test2 + %conv = fpext float %f to double + %call = call double @asin(double %conv) + ret double %call +; CHECK: call double @asin(double %conv) +} + +define float @asinh_test(float %f) nounwind readnone { +; CHECK: asinh_test + %conv = fpext float %f to double + %call = call double @asinh(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @asinhf(float %f) +} + +define double @asinh_test2(float %f) nounwind readnone { +; CHECK: asinh_test2 + %conv = fpext float %f to double + %call = call double @asinh(double %conv) + ret double %call +; CHECK: call double @asinh(double %conv) +} + +define float @atan_test(float %f) nounwind readnone { +; CHECK: atan_test + %conv = fpext float %f to double + %call = call double @atan(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @atanf(float %f) +} + +define double @atan_test2(float %f) nounwind readnone { +; CHECK: atan_test2 + %conv = fpext float %f to double + %call = call double @atan(double %conv) + ret double %call +; CHECK: call double @atan(double %conv) +} +define float @atanh_test(float %f) nounwind readnone { +; CHECK: atanh_test + %conv = fpext float %f to double + %call = call double @atanh(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @atanhf(float %f) +} + +define double @atanh_test2(float %f) nounwind readnone { +; CHECK: atanh_test2 + %conv = fpext float %f to double + %call = call double @atanh(double %conv) + ret double %call +; CHECK: call double @atanh(double %conv) +} +define float @cbrt_test(float %f) nounwind readnone { +; CHECK: cbrt_test + %conv = fpext float %f to double + %call = call double @cbrt(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @cbrtf(float %f) +} + +define double @cbrt_test2(float %f) nounwind readnone { +; CHECK: cbrt_test2 + %conv = fpext float %f to double + %call = call double @cbrt(double %conv) + ret double %call +; CHECK: call double @cbrt(double %conv) +} +define float @exp_test(float %f) nounwind readnone { +; CHECK: exp_test + %conv = fpext float %f to double + %call = call double @exp(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @expf(float %f) +} + +define double @exp_test2(float %f) nounwind readnone { +; CHECK: exp_test2 + %conv = fpext float %f to double + %call = call double @exp(double %conv) + ret double %call +; CHECK: call double @exp(double %conv) +} +define float @expm1_test(float %f) nounwind readnone { +; CHECK: expm1_test + %conv = fpext float %f to double + %call = call double @expm1(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @expm1f(float %f) +} + +define double @expm1_test2(float %f) nounwind readnone { +; CHECK: expm1_test2 + %conv = fpext float %f to double + %call = call double @expm1(double %conv) + ret double %call +; CHECK: call double @expm1(double %conv) +} +define float @exp10_test(float %f) nounwind readnone { +; CHECK: exp10_test + %conv = fpext float %f to double + %call = call double @exp10(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @exp10f(float %f) +} + +define double @exp10_test2(float %f) nounwind readnone { +; CHECK: exp10_test2 + %conv = fpext float %f to double + %call = call double @exp10(double %conv) + ret double %call +; CHECK: call double @exp10(double %conv) +} +define float @log_test(float %f) nounwind readnone { +; CHECK: log_test + %conv = fpext float %f to double + %call = call double @log(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @logf(float %f) +} + +define double @log_test2(float %f) nounwind readnone { +; CHECK: log_test2 + %conv = fpext float %f to double + %call = call double @log(double %conv) + ret double %call +; CHECK: call double @log(double %conv) +} +define float @log10_test(float %f) nounwind readnone { +; CHECK: log10_test + %conv = fpext float %f to double + %call = call double @log10(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @log10f(float %f) +} + +define double @log10_test2(float %f) nounwind readnone { +; CHECK: log10_test2 + %conv = fpext float %f to double + %call = call double @log10(double %conv) + ret double %call +; CHECK: call double @log10(double %conv) +} +define float @log1p_test(float %f) nounwind readnone { +; CHECK: log1p_test + %conv = fpext float %f to double + %call = call double @log1p(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @log1pf(float %f) +} + +define double @log1p_test2(float %f) nounwind readnone { +; CHECK: log1p_test2 + %conv = fpext float %f to double + %call = call double @log1p(double %conv) + ret double %call +; CHECK: call double @log1p(double %conv) +} +define float @log2_test(float %f) nounwind readnone { +; CHECK: log2_test + %conv = fpext float %f to double + %call = call double @log2(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @log2f(float %f) +} + +define double @log2_test2(float %f) nounwind readnone { +; CHECK: log2_test2 + %conv = fpext float %f to double + %call = call double @log2(double %conv) + ret double %call +; CHECK: call double @log2(double %conv) +} +define float @logb_test(float %f) nounwind readnone { +; CHECK: logb_test + %conv = fpext float %f to double + %call = call double @logb(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @logbf(float %f) +} + +define double @logb_test2(float %f) nounwind readnone { +; CHECK: logb_test2 + %conv = fpext float %f to double + %call = call double @logb(double %conv) + ret double %call +; CHECK: call double @logb(double %conv) +} +define float @sin_test(float %f) nounwind readnone { +; CHECK: sin_test + %conv = fpext float %f to double + %call = call double @sin(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @sinf(float %f) +} + +define double @sin_test2(float %f) nounwind readnone { +; CHECK: sin_test2 + %conv = fpext float %f to double + %call = call double @sin(double %conv) + ret double %call +; CHECK: call double @sin(double %conv) +} +define float @sqrt_test(float %f) nounwind readnone { +; CHECK: sqrt_test + %conv = fpext float %f to double + %call = call double @sqrt(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @sqrtf(float %f) +} + +define double @sqrt_test2(float %f) nounwind readnone { +; CHECK: sqrt_test2 + %conv = fpext float %f to double + %call = call double @sqrt(double %conv) + ret double %call +; CHECK: call double @sqrt(double %conv) +} +define float @tan_test(float %f) nounwind readnone { +; CHECK: tan_test + %conv = fpext float %f to double + %call = call double @tan(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @tanf(float %f) +} + +define double @tan_test2(float %f) nounwind readnone { +; CHECK: tan_test2 + %conv = fpext float %f to double + %call = call double @tan(double %conv) + ret double %call +; CHECK: call double @tan(double %conv) +} +define float @tanh_test(float %f) nounwind readnone { +; CHECK: tanh_test + %conv = fpext float %f to double + %call = call double @tanh(double %conv) + %conv1 = fptrunc double %call to float + ret float %conv1 +; CHECK: call float @tanhf(float %f) +} + +define double @tanh_test2(float %f) nounwind readnone { +; CHECK: tanh_test2 + %conv = fpext float %f to double + %call = call double @tanh(double %conv) + ret double %call +; CHECK: call double @tanh(double %conv) +} + +declare double @tanh(double) nounwind readnone +declare double @tan(double) nounwind readnone +declare double @sqrt(double) nounwind readnone +declare double @sin(double) nounwind readnone +declare double @log2(double) nounwind readnone +declare double @log1p(double) nounwind readnone +declare double @log10(double) nounwind readnone +declare double @log(double) nounwind readnone +declare double @logb(double) nounwind readnone +declare double @exp10(double) nounwind readnone +declare double @expm1(double) nounwind readnone +declare double @exp(double) nounwind readnone +declare double @cbrt(double) nounwind readnone +declare double @atanh(double) nounwind readnone +declare double @atan(double) nounwind readnone +declare double @acos(double) nounwind readnone +declare double @acosh(double) nounwind readnone +declare double @asin(double) nounwind readnone +declare double @asinh(double) nounwind readnone diff --git a/test/Transforms/SimplifyLibCalls/float-shrink-compare.ll b/test/Transforms/SimplifyLibCalls/float-shrink-compare.ll new file mode 100644 index 0000000..aecb887 --- /dev/null +++ b/test/Transforms/SimplifyLibCalls/float-shrink-compare.ll @@ -0,0 +1,179 @@ +; RUN: opt -S -simplify-libcalls -instcombine %s | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.8.0" + +define i32 @test1(float %x, float %y) nounwind uwtable { + %1 = fpext float %x to double + %2 = call double @ceil(double %1) nounwind readnone + %3 = fpext float %y to double + %4 = fcmp oeq double %2, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test1 +; CHECK-NEXT: %ceilf = call float @ceilf(float %x) +; CHECK-NEXT: fcmp oeq float %ceilf, %y +} + +define i32 @test2(float %x, float %y) nounwind uwtable { + %1 = fpext float %x to double + %2 = call double @fabs(double %1) nounwind readnone + %3 = fpext float %y to double + %4 = fcmp oeq double %2, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test2 +; CHECK-NEXT: %fabsf = call float @fabsf(float %x) +; CHECK-NEXT: fcmp oeq float %fabsf, %y +} + +define i32 @test3(float %x, float %y) nounwind uwtable { + %1 = fpext float %x to double + %2 = call double @floor(double %1) nounwind readnone + %3 = fpext float %y to double + %4 = fcmp oeq double %2, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test3 +; CHECK-NEXT: %floorf = call float @floorf(float %x) +; CHECK-NEXT: fcmp oeq float %floorf, %y +} + +define i32 @test4(float %x, float %y) nounwind uwtable { + %1 = fpext float %x to double + %2 = call double @nearbyint(double %1) nounwind + %3 = fpext float %y to double + %4 = fcmp oeq double %2, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test4 +; CHECK-NEXT: %nearbyintf = call float @nearbyintf(float %x) +; CHECK-NEXT: fcmp oeq float %nearbyintf, %y +} + +define i32 @test5(float %x, float %y) nounwind uwtable { + %1 = fpext float %x to double + %2 = call double @rint(double %1) nounwind + %3 = fpext float %y to double + %4 = fcmp oeq double %2, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test5 +; CHECK-NEXT: %rintf = call float @rintf(float %x) +; CHECK-NEXT: fcmp oeq float %rintf, %y +} + +define i32 @test6(float %x, float %y) nounwind uwtable { + %1 = fpext float %x to double + %2 = call double @round(double %1) nounwind readnone + %3 = fpext float %y to double + %4 = fcmp oeq double %2, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test6 +; CHECK-NEXT: %roundf = call float @roundf(float %x) +; CHECK-NEXT: fcmp oeq float %roundf, %y +} + +define i32 @test7(float %x, float %y) nounwind uwtable { + %1 = fpext float %x to double + %2 = call double @trunc(double %1) nounwind + %3 = fpext float %y to double + %4 = fcmp oeq double %2, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test7 +; CHECK-NEXT: %truncf = call float @truncf(float %x) +; CHECK-NEXT: fcmp oeq float %truncf, %y +} + +define i32 @test8(float %x, float %y) nounwind uwtable { + %1 = fpext float %y to double + %2 = fpext float %x to double + %3 = call double @ceil(double %2) nounwind readnone + %4 = fcmp oeq double %1, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test8 +; CHECK-NEXT: %ceilf = call float @ceilf(float %x) +; CHECK-NEXT: fcmp oeq float %ceilf, %y +} + +define i32 @test9(float %x, float %y) nounwind uwtable { + %1 = fpext float %y to double + %2 = fpext float %x to double + %3 = call double @fabs(double %2) nounwind readnone + %4 = fcmp oeq double %1, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test9 +; CHECK-NEXT: %fabsf = call float @fabsf(float %x) +; CHECK-NEXT: fcmp oeq float %fabsf, %y +} + +define i32 @test10(float %x, float %y) nounwind uwtable { + %1 = fpext float %y to double + %2 = fpext float %x to double + %3 = call double @floor(double %2) nounwind readnone + %4 = fcmp oeq double %1, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test10 +; CHECK-NEXT: %floorf = call float @floorf(float %x) +; CHECK-NEXT: fcmp oeq float %floorf, %y +} + +define i32 @test11(float %x, float %y) nounwind uwtable { + %1 = fpext float %y to double + %2 = fpext float %x to double + %3 = call double @nearbyint(double %2) nounwind + %4 = fcmp oeq double %1, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test11 +; CHECK-NEXT: %nearbyintf = call float @nearbyintf(float %x) +; CHECK-NEXT: fcmp oeq float %nearbyintf, %y +} + +define i32 @test12(float %x, float %y) nounwind uwtable { + %1 = fpext float %y to double + %2 = fpext float %x to double + %3 = call double @rint(double %2) nounwind + %4 = fcmp oeq double %1, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test12 +; CHECK-NEXT: %rintf = call float @rintf(float %x) +; CHECK-NEXT: fcmp oeq float %rintf, %y +} + +define i32 @test13(float %x, float %y) nounwind uwtable { + %1 = fpext float %y to double + %2 = fpext float %x to double + %3 = call double @round(double %2) nounwind readnone + %4 = fcmp oeq double %1, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test13 +; CHECK-NEXT: %roundf = call float @roundf(float %x) +; CHECK-NEXT: fcmp oeq float %roundf, %y +} + +define i32 @test14(float %x, float %y) nounwind uwtable { + %1 = fpext float %y to double + %2 = fpext float %x to double + %3 = call double @trunc(double %2) nounwind + %4 = fcmp oeq double %1, %3 + %5 = zext i1 %4 to i32 + ret i32 %5 +; CHECK: @test14 +; CHECK-NEXT: %truncf = call float @truncf(float %x) +; CHECK-NEXT: fcmp oeq float %truncf, %y +} + +declare double @fabs(double) nounwind readnone +declare double @ceil(double) nounwind readnone +declare double @floor(double) nounwind readnone +declare double @nearbyint(double) nounwind readnone +declare double @rint(double) nounwind readnone +declare double @round(double) nounwind readnone +declare double @trunc(double) nounwind readnone |