diff options
Diffstat (limited to 'test/Transforms/SimplifyCFG')
| -rw-r--r-- | test/Transforms/SimplifyCFG/PR17073.ll | 73 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/SPARC/lit.local.cfg | 3 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/X86/lit.local.cfg | 3 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/X86/switch-table-bug.ll | 41 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll | 167 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/basictest.ll | 30 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/extract-cost.ll | 22 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/no_speculative_loads_with_tsan.ll | 40 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/preserve-branchweights.ll | 84 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/speculate-math.ll | 58 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/speculate-vector-ops.ll | 60 | ||||
| -rw-r--r-- | test/Transforms/SimplifyCFG/trapping-load-unreachable.ll | 2 |
12 files changed, 574 insertions, 9 deletions
diff --git a/test/Transforms/SimplifyCFG/PR17073.ll b/test/Transforms/SimplifyCFG/PR17073.ll new file mode 100644 index 000000000000..8dc9fb28d617 --- /dev/null +++ b/test/Transforms/SimplifyCFG/PR17073.ll @@ -0,0 +1,73 @@ +; RUN: opt < %s -simplifycfg -S | FileCheck %s + +; In PR17073 ( http://llvm.org/pr17073 ), we illegally hoisted an operation that can trap. +; The first test confirms that we don't do that when the trapping op is reached by the current BB (block1). +; The second test confirms that we don't do that when the trapping op is reached by the previous BB (entry). +; The third test confirms that we can still do this optimization for an operation (add) that doesn't trap. +; The tests must be complicated enough to prevent previous SimplifyCFG actions from optimizing away +; the instructions that we're checking for. + +target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128" +target triple = "i386-apple-macosx10.9.0" + +@a = common global i32 0, align 4 +@b = common global i8 0, align 1 + +; CHECK-LABEL: can_trap1 +; CHECK-NOT: or i1 %tobool, icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) +; CHECK-NOT: select i1 %tobool, i32* null, i32* select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a) +define i32* @can_trap1() { +entry: + %0 = load i32* @a, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %exit, label %block1 + +block1: + br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), label %exit, label %block2 + +block2: + br label %exit + +exit: + %storemerge = phi i32* [ null, %entry ],[ null, %block2 ], [ select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), %block1 ] + ret i32* %storemerge +} + +; CHECK-LABEL: can_trap2 +; CHECK-NOT: or i1 %tobool, icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) +; CHECK-NOT: select i1 %tobool, i32* select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), i32* null +define i32* @can_trap2() { +entry: + %0 = load i32* @a, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %exit, label %block1 + +block1: + br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), label %exit, label %block2 + +block2: + br label %exit + +exit: + %storemerge = phi i32* [ select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), %entry ],[ null, %block2 ], [ null, %block1 ] + ret i32* %storemerge +} + +; CHECK-LABEL: cannot_trap +; CHECK: select i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), i32* select (i1 icmp eq (i64 add (i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64), i64 2), i64 0), i32* null, i32* @a), i32* null +define i32* @cannot_trap() { +entry: + %0 = load i32* @a, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %exit, label %block1 + +block1: + br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a), label %exit, label %block2 + +block2: + br label %exit + +exit: + %storemerge = phi i32* [ null, %entry ],[ null, %block2 ], [ select (i1 icmp eq (i64 add (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), %block1 ] + ret i32* %storemerge +} diff --git a/test/Transforms/SimplifyCFG/SPARC/lit.local.cfg b/test/Transforms/SimplifyCFG/SPARC/lit.local.cfg index 4d344fa91a9e..fa6a54e50132 100644 --- a/test/Transforms/SimplifyCFG/SPARC/lit.local.cfg +++ b/test/Transforms/SimplifyCFG/SPARC/lit.local.cfg @@ -1,4 +1,3 @@ -targets = set(config.root.targets_to_build.split()) -if not 'Sparc' in targets: +if not 'Sparc' in config.root.targets: config.unsupported = True diff --git a/test/Transforms/SimplifyCFG/X86/lit.local.cfg b/test/Transforms/SimplifyCFG/X86/lit.local.cfg index ba763cf03ffc..e71f3cc4c41e 100644 --- a/test/Transforms/SimplifyCFG/X86/lit.local.cfg +++ b/test/Transforms/SimplifyCFG/X86/lit.local.cfg @@ -1,4 +1,3 @@ -targets = set(config.root.targets_to_build.split()) -if not 'X86' in targets: +if not 'X86' in config.root.targets: config.unsupported = True diff --git a/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll b/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll new file mode 100644 index 000000000000..d0b8ab29d26b --- /dev/null +++ b/test/Transforms/SimplifyCFG/X86/switch-table-bug.ll @@ -0,0 +1,41 @@ +; RUN: opt -S -simplifycfg < %s -mtriple=x86_64-apple-darwin12.0.0 | FileCheck %s +; rdar://17735071 +target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-apple-darwin12.0.0" + +; When tableindex can't fit into i2, we should extend the type to i3. +; CHECK-LABEL: @_TFO6reduce1E5toRawfS0_FT_Si +; CHECK: entry: +; CHECK-NEXT: sub i2 %0, -2 +; CHECK-NEXT: zext i2 %switch.tableidx to i3 +; CHECK-NEXT: getelementptr inbounds [4 x i64]* @switch.table, i32 0, i3 %switch.tableidx.zext +; CHECK-NEXT: load i64* %switch.gep +; CHECK-NEXT: ret i64 %switch.load +define i64 @_TFO6reduce1E5toRawfS0_FT_Si(i2) { +entry: + switch i2 %0, label %1 [ + i2 0, label %2 + i2 1, label %3 + i2 -2, label %4 + i2 -1, label %5 + ] + +; <label>:1 ; preds = %entry + unreachable + +; <label>:2 ; preds = %2 + br label %6 + +; <label>:3 ; preds = %4 + br label %6 + +; <label>:4 ; preds = %6 + br label %6 + +; <label>:5 ; preds = %8 + br label %6 + +; <label>:6 ; preds = %3, %5, %7, %9 + %7 = phi i64 [ 3, %5 ], [ 2, %4 ], [ 1, %3 ], [ 0, %2 ] + ret i64 %7 +} diff --git a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll index 368732711a70..51ced4099ac9 100644 --- a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll +++ b/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll @@ -806,3 +806,170 @@ return: ; CHECK-NOT: @switch.table ; CHECK: switch i32 %c } + +; If we can build a lookup table without any holes, we don't need a default result. +declare void @exit(i32) +define i32 @nodefaultnoholes(i32 %c) { +entry: + switch i32 %c, 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: call void @exit(i32 1) + unreachable +return: + %x = phi i32 [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ] + ret i32 %x + +; CHECK-LABEL: @nodefaultnoholes( +; CHECK: @switch.table +; CHECK-NOT: switch i32 +} + +; This lookup table will have holes, so we need to test for the holes. +define i32 @nodefaultwithholes(i32 %c) { +entry: + switch i32 %c, label %sw.default [ + i32 0, label %return + i32 1, label %sw.bb1 + i32 2, label %sw.bb2 + i32 3, label %sw.bb3 + i32 5, label %sw.bb3 + ] + +sw.bb1: br label %return +sw.bb2: br label %return +sw.bb3: br label %return +sw.default: call void @exit(i32 1) + unreachable +return: + %x = phi i32 [ -1, %sw.bb3 ], [ 0, %sw.bb2 ], [ 123, %sw.bb1 ], [ 55, %entry ] + ret i32 %x + +; CHECK-LABEL: @nodefaultwithholes( +; CHECK: entry: +; CHECK: br i1 %{{.*}}, label %switch.hole_check, label %sw.default +; CHECK: switch.hole_check: +; CHECK-NEXT: %switch.maskindex = trunc i32 %switch.tableidx to i6 +; CHECK-NEXT: %switch.shifted = lshr i6 -17, %switch.maskindex +; The mask is binary 101111. +; CHECK-NEXT: %switch.lobit = trunc i6 %switch.shifted to i1 +; CHECK-NEXT: br i1 %switch.lobit, label %switch.lookup, label %sw.default +; CHECK-NOT: switch i32 +} + +; We don't build lookup tables with holes for switches with less than four cases. +define i32 @threecasesholes(i32 %c) { +entry: + switch i32 %c, label %sw.default [ + i32 0, label %return + i32 1, label %sw.bb1 + i32 3, label %sw.bb2 + ] +sw.bb1: br label %return +sw.bb2: br label %return +sw.default: br label %return +return: + %x = phi i32 [ %c, %sw.default ], [ 5, %sw.bb2 ], [ 7, %sw.bb1 ], [ 9, %entry ] + ret i32 %x +; CHECK-LABEL: @threecasesholes( +; CHECK: switch i32 +; CHECK-NOT: @switch.table +} + +; We build lookup tables for switches with three or more cases. +define i32 @threecases(i32 %c) { +entry: + switch i32 %c, label %sw.default [ + i32 0, label %return + i32 1, label %sw.bb1 + i32 2, label %sw.bb2 + ] +sw.bb1: br label %return +sw.bb2: br label %return +sw.default: br label %return +return: + %x = phi i32 [ 3, %sw.default ], [ 5, %sw.bb2 ], [ 7, %sw.bb1 ], [ 9, %entry ] + ret i32 %x +; CHECK-LABEL: @threecases( +; CHECK-NOT: switch i32 +; CHECK: @switch.table +} + +; We don't build tables for switches with two cases. +define i32 @twocases(i32 %c) { +entry: + switch i32 %c, label %sw.default [ + i32 0, label %return + i32 1, label %sw.bb1 + ] +sw.bb1: br label %return +sw.default: br label %return +return: + %x = phi i32 [ 3, %sw.default ], [ 7, %sw.bb1 ], [ 9, %entry ] + ret i32 %x +; CHECK-LABEL: @twocases( +; CHECK: switch i32 +; CHECK-NOT: @switch.table +} + +; Don't build tables for switches with TLS variables. +@tls_a = thread_local global i32 0 +@tls_b = thread_local global i32 0 +@tls_c = thread_local global i32 0 +@tls_d = thread_local global i32 0 +define i32* @tls(i32 %x) { +entry: + switch i32 %x, label %sw.default [ + i32 0, label %return + i32 1, label %sw.bb1 + i32 2, label %sw.bb2 + ] +sw.bb1: + br label %return +sw.bb2: + br label %return +sw.default: + br label %return +return: + %retval.0 = phi i32* [ @tls_d, %sw.default ], [ @tls_c, %sw.bb2 ], [ @tls_b, %sw.bb1 ], [ @tls_a, %entry ] + ret i32* %retval.0 +; CHECK-LABEL: @tls( +; CHECK: switch i32 +; CHECK-NOT: @switch.table +} + +; Don't build tables for switches with dllimport variables. +@dllimport_a = external dllimport global [3x i32] +@dllimport_b = external dllimport global [3x i32] +@dllimport_c = external dllimport global [3x i32] +@dllimport_d = external dllimport global [3x i32] +define i32* @dllimport(i32 %x) { +entry: + switch i32 %x, label %sw.default [ + i32 0, label %return + i32 1, label %sw.bb1 + i32 2, label %sw.bb2 + ] +sw.bb1: + br label %return +sw.bb2: + br label %return +sw.default: + br label %return +return: + %retval.0 = phi i32* [ getelementptr inbounds ([3 x i32]* @dllimport_d, i32 0, i32 0), %sw.default ], + [ getelementptr inbounds ([3 x i32]* @dllimport_c, i32 0, i32 0), %sw.bb2 ], + [ getelementptr inbounds ([3 x i32]* @dllimport_b, i32 0, i32 0), %sw.bb1 ], + [ getelementptr inbounds ([3 x i32]* @dllimport_a, i32 0, i32 0), %entry ] + ret i32* %retval.0 +; CHECK-LABEL: @dllimport( +; CHECK: switch i32 +; CHECK-NOT: @switch.table +} diff --git a/test/Transforms/SimplifyCFG/basictest.ll b/test/Transforms/SimplifyCFG/basictest.ll index 9c4edd68b800..d6958a9c111a 100644 --- a/test/Transforms/SimplifyCFG/basictest.ll +++ b/test/Transforms/SimplifyCFG/basictest.ll @@ -41,3 +41,33 @@ return: ; preds = %entry ; CHECK-LABEL: @test5( ; CHECK-NEXT: ret void } + + +; PR14893 +define i8 @test6f() { +; CHECK-LABEL: @test6f +; CHECK: alloca i8, align 1 +; CHECK-NEXT: call i8 @test6g +; CHECK-NEXT: icmp eq i8 %tmp, 0 +; CHECK-NEXT: load i8* %r, align 1{{$}} + +bb0: + %r = alloca i8, align 1 + %tmp = call i8 @test6g(i8* %r) + %tmp1 = icmp eq i8 %tmp, 0 + br i1 %tmp1, label %bb2, label %bb1 +bb1: + %tmp3 = load i8* %r, align 1, !range !2, !tbaa !1 + %tmp4 = icmp eq i8 %tmp3, 1 + br i1 %tmp4, label %bb2, label %bb3 +bb2: + br label %bb3 +bb3: + %tmp6 = phi i8 [ 0, %bb2 ], [ 1, %bb1 ] + ret i8 %tmp6 +} +declare i8 @test6g(i8*) + +!0 = metadata !{metadata !1, metadata !1, i64 0} +!1 = metadata !{metadata !"foo"} +!2 = metadata !{i8 0, i8 2} diff --git a/test/Transforms/SimplifyCFG/extract-cost.ll b/test/Transforms/SimplifyCFG/extract-cost.ll new file mode 100644 index 000000000000..9c867256e783 --- /dev/null +++ b/test/Transforms/SimplifyCFG/extract-cost.ll @@ -0,0 +1,22 @@ +; RUN: opt -simplifycfg -S < %s | FileCheck %s + +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) #1 + +define i32 @f(i32 %a, i32 %b) #0 { +entry: + %uadd = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b) + %cmp = extractvalue { i32, i1 } %uadd, 1 + br i1 %cmp, label %return, label %if.end + +if.end: ; preds = %entry + %0 = extractvalue { i32, i1 } %uadd, 0 + br label %return + +return: ; preds = %entry, %if.end + %retval.0 = phi i32 [ %0, %if.end ], [ 0, %entry ] + ret i32 %retval.0 + +; CHECK-LABEL: @f( +; CHECK-NOT: phi +; CHECK: select +} diff --git a/test/Transforms/SimplifyCFG/no_speculative_loads_with_tsan.ll b/test/Transforms/SimplifyCFG/no_speculative_loads_with_tsan.ll new file mode 100644 index 000000000000..b388cc5830f4 --- /dev/null +++ b/test/Transforms/SimplifyCFG/no_speculative_loads_with_tsan.ll @@ -0,0 +1,40 @@ +; RUN: opt -simplifycfg -S %s | FileCheck %s +; Make sure we don't speculate loads under ThreadSanitizer. +@g = global i32 0, align 4 + +define i32 @TestNoTsan(i32 %cond) nounwind readonly uwtable { +entry: + %tobool = icmp eq i32 %cond, 0 + br i1 %tobool, label %return, label %if.then + +if.then: ; preds = %entry + %0 = load i32* @g, align 4 + br label %return + +return: ; preds = %entry, %if.then + %retval = phi i32 [ %0, %if.then ], [ 0, %entry ] + ret i32 %retval +; CHECK-LABEL: @TestNoTsan +; CHECK: %[[LOAD:[^ ]*]] = load +; CHECK: select{{.*}}[[LOAD]] +; CHECK: ret i32 +} + +define i32 @TestTsan(i32 %cond) nounwind readonly uwtable sanitize_thread { +entry: + %tobool = icmp eq i32 %cond, 0 + br i1 %tobool, label %return, label %if.then + +if.then: ; preds = %entry + %0 = load i32* @g, align 4 + br label %return + +return: ; preds = %entry, %if.then + %retval = phi i32 [ %0, %if.then ], [ 0, %entry ] + ret i32 %retval +; CHECK-LABEL: @TestTsan +; CHECK: br i1 +; CHECK: load i32* @g +; CHECK: br label +; CHECK: ret i32 +} diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights.ll b/test/Transforms/SimplifyCFG/preserve-branchweights.ll index 4022ed6927ee..bdd25ba80585 100644 --- a/test/Transforms/SimplifyCFG/preserve-branchweights.ll +++ b/test/Transforms/SimplifyCFG/preserve-branchweights.ll @@ -87,7 +87,7 @@ entry: i32 2, label %sw.bb i32 3, label %sw.bb1 ], !prof !3 -; CHECK: test5 +; CHECK-LABEL: @test5( ; CHECK: switch i32 %N, label %sw2 [ ; CHECK: i32 3, label %sw.bb1 ; CHECK: i32 2, label %sw.bb @@ -119,7 +119,7 @@ entry: i32 2, label %sw.bb i32 3, label %sw.bb1 ], !prof !4 -; CHECK: test6 +; CHECK-LABEL: @test6( ; CHECK: switch i32 %N, label %sw.epilog ; CHECK: i32 3, label %sw.bb1 ; CHECK: i32 2, label %sw.bb @@ -266,7 +266,7 @@ lor.end: call void @helper(i32 0) nounwind ret void -; CHECK: test10 +; CHECK-LABEL: @test10( ; CHECK: %x.off = add i32 %x, -1 ; CHECK: %switch = icmp ult i32 %x.off, 3 ; CHECK: br i1 %switch, label %lor.end, label %lor.rhs, !prof !8 @@ -279,6 +279,7 @@ define void @test11(i32 %x) nounwind { i32 21, label %b i32 24, label %c ], !prof !8 +; CHECK-LABEL: @test11( ; CHECK: %cond = icmp eq i32 %i, 24 ; CHECK: br i1 %cond, label %c, label %a, !prof !9 @@ -293,6 +294,76 @@ c: ret void } +;; test12 - Don't crash if the whole switch is removed +define void @test12(i32 %M, i32 %N) nounwind uwtable { +entry: + switch i32 %N, label %sw.bb [ + i32 1, label %sw.bb + ], !prof !9 +; CHECK-LABEL: @test12( +; CHECK-NEXT: entry: +; CHECK-NEXT: call void @helper +; CHECK-NEXT: ret void + +sw.bb: + call void @helper(i32 0) + br label %sw.epilog + +sw.epilog: + ret void +} + +;; If every case is dead, make sure they are all removed. This used to +;; crash trying to merge the metadata. +define void @test13(i32 %x) nounwind { +entry: + %i = shl i32 %x, 1 + switch i32 %i, label %a [ + i32 21, label %b + i32 25, label %c + ], !prof !8 +; CHECK-LABEL: @test13( +; CHECK-NEXT: entry: +; CHECK-NEXT: call void @helper +; CHECK-NEXT: ret void + +a: + call void @helper(i32 0) nounwind + ret void +b: + call void @helper(i32 1) nounwind + ret void +c: + call void @helper(i32 2) nounwind + ret void +} + +;; When folding branches to common destination, the updated branch weights +;; can exceed uint32 by more than factor of 2. We should keep halving the +;; weights until they can fit into uint32. +@max_regno = common global i32 0, align 4 +define void @test14(i32* %old, i32 %final) { +; CHECK-LABEL: @test14 +; CHECK: br i1 %or.cond, label %for.exit, label %for.inc, !prof !10 +for.cond: + br label %for.cond2 +for.cond2: + %i.1 = phi i32 [ %inc19, %for.inc ], [ 0, %for.cond ] + %bit.0 = phi i32 [ %shl, %for.inc ], [ 1, %for.cond ] + %tobool = icmp eq i32 %bit.0, 0 + br i1 %tobool, label %for.exit, label %for.body3, !prof !10 +for.body3: + %v3 = load i32* @max_regno, align 4 + %cmp4 = icmp eq i32 %i.1, %v3 + br i1 %cmp4, label %for.exit, label %for.inc, !prof !11 +for.inc: + %shl = shl i32 %bit.0, 1 + %inc19 = add nsw i32 %i.1, 1 + br label %for.cond2 +for.exit: + ret void +} + !0 = metadata !{metadata !"branch_weights", i32 3, i32 5} !1 = metadata !{metadata !"branch_weights", i32 1, i32 1} !2 = metadata !{metadata !"branch_weights", i32 1, i32 2} @@ -302,6 +373,9 @@ c: !6 = metadata !{metadata !"branch_weights", i32 1, i32 3} !7 = metadata !{metadata !"branch_weights", i32 33, i32 9, i32 8, i32 7} !8 = metadata !{metadata !"branch_weights", i32 33, i32 9, i32 8} +!9 = metadata !{metadata !"branch_weights", i32 7, i32 6} +!10 = metadata !{metadata !"branch_weights", i32 672646, i32 21604207} +!11 = metadata !{metadata !"branch_weights", i32 6960, i32 21597248} ; CHECK: !0 = metadata !{metadata !"branch_weights", i32 5, i32 11} ; CHECK: !1 = metadata !{metadata !"branch_weights", i32 1, i32 5} @@ -313,4 +387,6 @@ c: ; CHECK: !7 = metadata !{metadata !"branch_weights", i32 17, i32 9, i32 8, i32 7, i32 17} ; CHECK: !8 = metadata !{metadata !"branch_weights", i32 24, i32 33} ; CHECK: !9 = metadata !{metadata !"branch_weights", i32 8, i32 33} -; CHECK-NOT: !9 +;; The false weight prints out as a negative integer here, but inside llvm, we +;; treat the weight as an unsigned integer. +; CHECK: !10 = metadata !{metadata !"branch_weights", i32 112017436, i32 -735157296} diff --git a/test/Transforms/SimplifyCFG/speculate-math.ll b/test/Transforms/SimplifyCFG/speculate-math.ll new file mode 100644 index 000000000000..fa7976d0689f --- /dev/null +++ b/test/Transforms/SimplifyCFG/speculate-math.ll @@ -0,0 +1,58 @@ +; RUN: opt -S -simplifycfg -phi-node-folding-threshold=2 < %s | FileCheck %s + +declare float @llvm.sqrt.f32(float) nounwind readonly +declare float @llvm.fma.f32(float, float, float) nounwind readonly +declare float @llvm.fmuladd.f32(float, float, float) nounwind readonly + +; CHECK-LABEL: @sqrt_test( +; CHECK: select +define void @sqrt_test(float addrspace(1)* noalias nocapture %out, float %a) nounwind { +entry: + %cmp.i = fcmp olt float %a, 0.000000e+00 + br i1 %cmp.i, label %test_sqrt.exit, label %cond.else.i + +cond.else.i: ; preds = %entry + %0 = tail call float @llvm.sqrt.f32(float %a) nounwind readnone + br label %test_sqrt.exit + +test_sqrt.exit: ; preds = %cond.else.i, %entry + %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ] + store float %cond.i, float addrspace(1)* %out, align 4 + ret void +} + + +; CHECK-LABEL: @fma_test( +; CHECK: select +define void @fma_test(float addrspace(1)* noalias nocapture %out, float %a, float %b, float %c) nounwind { +entry: + %cmp.i = fcmp olt float %a, 0.000000e+00 + br i1 %cmp.i, label %test_fma.exit, label %cond.else.i + +cond.else.i: ; preds = %entry + %0 = tail call float @llvm.fma.f32(float %a, float %b, float %c) nounwind readnone + br label %test_fma.exit + +test_fma.exit: ; preds = %cond.else.i, %entry + %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ] + store float %cond.i, float addrspace(1)* %out, align 4 + ret void +} + +; CHECK-LABEL: @fmuladd_test( +; CHECK: select +define void @fmuladd_test(float addrspace(1)* noalias nocapture %out, float %a, float %b, float %c) nounwind { +entry: + %cmp.i = fcmp olt float %a, 0.000000e+00 + br i1 %cmp.i, label %test_fmuladd.exit, label %cond.else.i + +cond.else.i: ; preds = %entry + %0 = tail call float @llvm.fmuladd.f32(float %a, float %b, float %c) nounwind readnone + br label %test_fmuladd.exit + +test_fmuladd.exit: ; preds = %cond.else.i, %entry + %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ] + store float %cond.i, float addrspace(1)* %out, align 4 + ret void +} + diff --git a/test/Transforms/SimplifyCFG/speculate-vector-ops.ll b/test/Transforms/SimplifyCFG/speculate-vector-ops.ll new file mode 100644 index 000000000000..91972eb5dd9f --- /dev/null +++ b/test/Transforms/SimplifyCFG/speculate-vector-ops.ll @@ -0,0 +1,60 @@ +; RUN: opt -S -simplifycfg < %s | FileCheck %s + +define i32 @speculate_vector_extract(i32 %d, <4 x i32> %v) #0 { +; CHECK-LABEL: @speculate_vector_extract( +; CHECK-NOT: br +entry: + %conv = insertelement <4 x i32> undef, i32 %d, i32 0 + %conv2 = insertelement <4 x i32> %conv, i32 %d, i32 1 + %conv3 = insertelement <4 x i32> %conv2, i32 %d, i32 2 + %conv4 = insertelement <4 x i32> %conv3, i32 %d, i32 3 + %tmp6 = add nsw <4 x i32> %conv4, <i32 0, i32 -1, i32 -2, i32 -3> + %cmp = icmp eq <4 x i32> %tmp6, zeroinitializer + %cmp.ext = sext <4 x i1> %cmp to <4 x i32> + %tmp8 = extractelement <4 x i32> %cmp.ext, i32 0 + %tobool = icmp eq i32 %tmp8, 0 + br i1 %tobool, label %cond.else, label %cond.then + +return: ; preds = %cond.end28 + ret i32 %cond32 + +cond.then: ; preds = %entry + %tmp10 = extractelement <4 x i32> %v, i32 0 + br label %cond.end + +cond.else: ; preds = %entry + %tmp12 = extractelement <4 x i32> %v, i32 3 + br label %cond.end + +cond.end: ; preds = %cond.else, %cond.then + %cond = phi i32 [ %tmp10, %cond.then ], [ %tmp12, %cond.else ] + %tmp14 = extractelement <4 x i32> %cmp.ext, i32 1 + %tobool15 = icmp eq i32 %tmp14, 0 + br i1 %tobool15, label %cond.else17, label %cond.then16 + +cond.then16: ; preds = %cond.end + %tmp20 = extractelement <4 x i32> %v, i32 1 + br label %cond.end18 + +cond.else17: ; preds = %cond.end + br label %cond.end18 + +cond.end18: ; preds = %cond.else17, %cond.then16 + %cond22 = phi i32 [ %tmp20, %cond.then16 ], [ %cond, %cond.else17 ] + %tmp24 = extractelement <4 x i32> %cmp.ext, i32 2 + %tobool25 = icmp eq i32 %tmp24, 0 + br i1 %tobool25, label %cond.else27, label %cond.then26 + +cond.then26: ; preds = %cond.end18 + %tmp30 = extractelement <4 x i32> %v, i32 2 + br label %cond.end28 + +cond.else27: ; preds = %cond.end18 + br label %cond.end28 + +cond.end28: ; preds = %cond.else27, %cond.then26 + %cond32 = phi i32 [ %tmp30, %cond.then26 ], [ %cond22, %cond.else27 ] + br label %return +} + +attributes #0 = { nounwind } diff --git a/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll b/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll index e9d93e834a50..5ae62af54581 100644 --- a/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll +++ b/test/Transforms/SimplifyCFG/trapping-load-unreachable.ll @@ -65,7 +65,7 @@ define void @test5(i1 %C, i32* %P) { entry: br i1 %C, label %T, label %F T: - cmpxchg volatile i32* %P, i32 0, i32 1 seq_cst + cmpxchg volatile i32* %P, i32 0, i32 1 seq_cst seq_cst unreachable F: ret void |
