aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/SimplifyCFG
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/SimplifyCFG')
-rw-r--r--test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll4
-rw-r--r--test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll16
-rw-r--r--test/Transforms/SimplifyCFG/AArch64/lit.local.cfg5
-rw-r--r--test/Transforms/SimplifyCFG/AArch64/prefer-fma.ll72
-rw-r--r--test/Transforms/SimplifyCFG/PhiBlockMerge.ll4
-rw-r--r--test/Transforms/SimplifyCFG/PowerPC/cttz-ctlz-spec.ll45
-rw-r--r--test/Transforms/SimplifyCFG/PowerPC/lit.local.cfg2
-rw-r--r--test/Transforms/SimplifyCFG/R600/cttz-ctlz.ll249
-rw-r--r--test/Transforms/SimplifyCFG/R600/lit.local.cfg2
-rw-r--r--test/Transforms/SimplifyCFG/SpeculativeExec.ll16
-rw-r--r--test/Transforms/SimplifyCFG/UnreachableEliminate.ll26
-rw-r--r--test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll330
-rw-r--r--test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll211
-rw-r--r--test/Transforms/SimplifyCFG/basictest.ll7
-rw-r--r--test/Transforms/SimplifyCFG/branch-fold-dbg.ll34
-rw-r--r--test/Transforms/SimplifyCFG/clamp.ll22
-rw-r--r--test/Transforms/SimplifyCFG/hoist-dbgvalue.ll52
-rw-r--r--test/Transforms/SimplifyCFG/hoist-with-range.ll6
-rw-r--r--test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll2
-rw-r--r--test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll18
-rw-r--r--test/Transforms/SimplifyCFG/preserve-branchweights.ll48
-rw-r--r--test/Transforms/SimplifyCFG/seh-nounwind.ll31
-rw-r--r--test/Transforms/SimplifyCFG/select-gep.ll23
-rw-r--r--test/Transforms/SimplifyCFG/sink-common-code.ll34
-rw-r--r--test/Transforms/SimplifyCFG/switch-range-to-icmp.ll77
-rw-r--r--test/Transforms/SimplifyCFG/switch-to-br.ll64
-rw-r--r--test/Transforms/SimplifyCFG/switch-to-select-two-case.ll35
-rw-r--r--test/Transforms/SimplifyCFG/trap-debugloc.ll22
-rw-r--r--test/Transforms/SimplifyCFG/trivial-throw.ll77
-rw-r--r--test/Transforms/SimplifyCFG/volatile-phioper.ll2
30 files changed, 1245 insertions, 291 deletions
diff --git a/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll b/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll
index a90e072..76f41e8 100644
--- a/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll
+++ b/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll
@@ -12,5 +12,9 @@ Cont: ; preds = %0
ret i32 0
Other: ; preds = %0
+ landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
+ catch i8* null
ret i32 1
}
+
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll b/test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll
index cf29b71..8e15637 100644
--- a/test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll
+++ b/test/Transforms/SimplifyCFG/2008-01-02-hoist-fp-add.ll
@@ -1,27 +1,27 @@
-; The phi should not be eliminated in this case, because the fp op could trap.
+; The phi should not be eliminated in this case, because the divide op could trap.
; RUN: opt < %s -simplifycfg -S | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
target triple = "i686-apple-darwin8"
-@G = weak global double 0.000000e+00, align 8 ; <double*> [#uses=2]
+@G = weak global i32 0, align 8 ; <i32*> [#uses=2]
-define void @test(i32 %X, i32 %Y, double %Z) {
+define void @test(i32 %X, i32 %Y, i32 %Z) {
entry:
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- %tmp = load double* @G, align 8 ; <double> [#uses=2]
+ %tmp = load i32* @G, align 8 ; <i32> [#uses=2]
%tmp3 = icmp eq i32 %X, %Y ; <i1> [#uses=1]
%tmp34 = zext i1 %tmp3 to i8 ; <i8> [#uses=1]
%toBool = icmp ne i8 %tmp34, 0 ; <i1> [#uses=1]
br i1 %toBool, label %cond_true, label %cond_next
cond_true: ; preds = %entry
- %tmp7 = fadd double %tmp, %Z ; <double> [#uses=1]
+ %tmp7 = udiv i32 %tmp, %Z ; <i32> [#uses=1]
br label %cond_next
cond_next: ; preds = %cond_true, %entry
-; CHECK: = phi double
- %F.0 = phi double [ %tmp, %entry ], [ %tmp7, %cond_true ] ; <double> [#uses=1]
- store double %F.0, double* @G, align 8
+; CHECK: = phi i32
+ %F.0 = phi i32 [ %tmp, %entry ], [ %tmp7, %cond_true ] ; <i32> [#uses=1]
+ store i32 %F.0, i32* @G, align 8
ret void
}
diff --git a/test/Transforms/SimplifyCFG/AArch64/lit.local.cfg b/test/Transforms/SimplifyCFG/AArch64/lit.local.cfg
new file mode 100644
index 0000000..6642d28
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/AArch64/lit.local.cfg
@@ -0,0 +1,5 @@
+config.suffixes = ['.ll']
+
+targets = set(config.root.targets_to_build.split())
+if not 'AArch64' in targets:
+ config.unsupported = True
diff --git a/test/Transforms/SimplifyCFG/AArch64/prefer-fma.ll b/test/Transforms/SimplifyCFG/AArch64/prefer-fma.ll
new file mode 100644
index 0000000..076cb58
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/AArch64/prefer-fma.ll
@@ -0,0 +1,72 @@
+; RUN: opt < %s -mtriple=aarch64-linux-gnu -simplifycfg -enable-unsafe-fp-math -S >%t
+; RUN: FileCheck %s < %t
+; ModuleID = 't.cc'
+
+; Function Attrs: nounwind
+define double @_Z3fooRdS_S_S_(double* dereferenceable(8) %x, double* dereferenceable(8) %y, double* dereferenceable(8) %a) #0 {
+entry:
+ %0 = load double* %y, align 8
+ %cmp = fcmp oeq double %0, 0.000000e+00
+ %1 = load double* %x, align 8
+ br i1 %cmp, label %if.then, label %if.else
+
+; fadd (const, (fmul x, y))
+if.then: ; preds = %entry
+; CHECK-LABEL: if.then:
+; CHECK: %3 = fmul fast double %1, %2
+; CHECK-NEXT: %mul = fadd fast double 1.000000e+00, %3
+ %2 = load double* %a, align 8
+ %3 = fmul fast double %1, %2
+ %mul = fadd fast double 1.000000e+00, %3
+ store double %mul, double* %y, align 8
+ br label %if.end
+
+; fsub ((fmul x, y), z)
+if.else: ; preds = %entry
+; CHECK-LABEL: if.else:
+; CHECK: %mul1 = fmul fast double %1, %2
+; CHECK-NEXT: %sub1 = fsub fast double %mul1, %0
+ %4 = load double* %a, align 8
+ %mul1 = fmul fast double %1, %4
+ %sub1 = fsub fast double %mul1, %0
+ store double %sub1, double* %y, align 8
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %5 = load double* %y, align 8
+ %cmp2 = fcmp oeq double %5, 2.000000e+00
+ %6 = load double* %x, align 8
+ br i1 %cmp2, label %if.then2, label %if.else2
+
+; fsub (x, (fmul y, z))
+if.then2: ; preds = %entry
+; CHECK-LABEL: if.then2:
+; CHECK: %7 = fmul fast double %5, 3.000000e+00
+; CHECK-NEXT: %mul2 = fsub fast double %6, %7
+ %7 = load double* %a, align 8
+ %8 = fmul fast double %6, 3.0000000e+00
+ %mul2 = fsub fast double %7, %8
+ store double %mul2, double* %y, align 8
+ br label %if.end2
+
+; fsub (fneg((fmul x, y)), const)
+if.else2: ; preds = %entry
+; CHECK-LABEL: if.else2:
+; CHECK: %mul3 = fmul fast double %5, 3.000000e+00
+; CHECK-NEXT: %neg = fsub fast double 0.000000e+00, %mul3
+; CHECK-NEXT: %sub2 = fsub fast double %neg, 3.000000e+00
+ %mul3 = fmul fast double %6, 3.0000000e+00
+ %neg = fsub fast double 0.0000000e+00, %mul3
+ %sub2 = fsub fast double %neg, 3.0000000e+00
+ store double %sub2, double* %y, align 8
+ br label %if.end2
+
+if.end2: ; preds = %if.else, %if.then
+ %9 = load double* %x, align 8
+ %10 = load double* %y, align 8
+ %add = fadd fast double %9, %10
+ %11 = load double* %a, align 8
+ %add2 = fadd fast double %add, %11
+ ret double %add2
+}
+
diff --git a/test/Transforms/SimplifyCFG/PhiBlockMerge.ll b/test/Transforms/SimplifyCFG/PhiBlockMerge.ll
index 36b52f5..5550829 100644
--- a/test/Transforms/SimplifyCFG/PhiBlockMerge.ll
+++ b/test/Transforms/SimplifyCFG/PhiBlockMerge.ll
@@ -4,9 +4,7 @@
;
define i32 @test(i1 %a, i1 %b) {
-; CHECK: br i1 %a
br i1 %a, label %M, label %O
-; CHECK: O:
O: ; preds = %0
; CHECK: select i1 %b, i32 0, i32 1
; CHECK-NOT: phi
@@ -18,9 +16,9 @@ N: ; preds = %Q, %O
%Wp = phi i32 [ 0, %O ], [ 1, %Q ] ; <i32> [#uses=1]
br label %M
M: ; preds = %N, %0
-; CHECK: %W = phi i32
%W = phi i32 [ %Wp, %N ], [ 2, %0 ] ; <i32> [#uses=1]
%R = add i32 %W, 1 ; <i32> [#uses=1]
ret i32 %R
+; CHECK: ret
}
diff --git a/test/Transforms/SimplifyCFG/PowerPC/cttz-ctlz-spec.ll b/test/Transforms/SimplifyCFG/PowerPC/cttz-ctlz-spec.ll
new file mode 100644
index 0000000..fa74549
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/PowerPC/cttz-ctlz-spec.ll
@@ -0,0 +1,45 @@
+; RUN: opt -S -simplifycfg < %s | FileCheck %s
+target datalayout = "E-m:e-i64:64-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+define i64 @test1(i64 %A) {
+; CHECK-LABEL: @test1(
+; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; CHECK-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 64, i64 [[CTLZ]]
+; CHECK-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+define i64 @test1b(i64 %A) {
+; CHECK-LABEL: @test1b(
+; CHECK: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; CHECK-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+; CHECK-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 64, i64 [[CTLZ]]
+; CHECK-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
+
diff --git a/test/Transforms/SimplifyCFG/PowerPC/lit.local.cfg b/test/Transforms/SimplifyCFG/PowerPC/lit.local.cfg
new file mode 100644
index 0000000..0913324
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/PowerPC/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'PowerPC' in config.root.targets:
+ config.unsupported = True
diff --git a/test/Transforms/SimplifyCFG/R600/cttz-ctlz.ll b/test/Transforms/SimplifyCFG/R600/cttz-ctlz.ll
new file mode 100644
index 0000000..5b27994
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/R600/cttz-ctlz.ll
@@ -0,0 +1,249 @@
+; RUN: opt -S -simplifycfg -mtriple=r600-unknown-unknown -mcpu=SI < %s | FileCheck -check-prefix=SI -check-prefix=ALL %s
+; RUN: opt -S -simplifycfg -mtriple=r600-unknown-unknown -mcpu=tonga < %s | FileCheck -check-prefix=SI -check-prefix=ALL %s
+
+
+define i64 @test1(i64 %A) {
+; ALL-LABEL: @test1(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; SI-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 64, i64 [[CTLZ]]
+; SI-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+
+define i32 @test2(i32 %A) {
+; ALL-LABEL: @test2(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; SI-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTLZ]]
+; SI-NEXT: ret i32 [[SEL]]
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3(i16 signext %A) {
+; ALL-LABEL: @test3(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; SI-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i16 16, i16 [[CTLZ]]
+; SI-NEXT: ret i16 [[SEL]]
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
+ ret i16 %cond
+}
+
+
+define i64 @test1b(i64 %A) {
+; ALL-LABEL: @test1b(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; SI-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 64, i64 [[CTTZ]]
+; SI-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+
+define i32 @test2b(i32 %A) {
+; ALL-LABEL: @test2b(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; SI-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 32, i32 [[CTTZ]]
+; SI-NEXT: ret i32 [[SEL]]
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3b(i16 signext %A) {
+; ALL-LABEL: @test3b(
+; SI: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; SI-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+; SI-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i16 16, i16 [[CTTZ]]
+; SI-NEXT: ret i16 [[SEL]]
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
+ ret i16 %cond
+}
+
+
+define i64 @test1c(i64 %A) {
+; ALL-LABEL: @test1c(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; ALL-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 63, i64 [[CTLZ]]
+; ALL-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 63, %entry ]
+ ret i64 %cond
+}
+
+define i32 @test2c(i32 %A) {
+; ALL-LABEL: @test2c(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; ALL-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 31, i32 [[CTLZ]]
+; ALL-NEXT: ret i32 [[SEL]]
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 31, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3c(i16 signext %A) {
+; ALL-LABEL: @test3c(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; ALL-NEXT: [[CTLZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i16 15, i16 [[CTLZ]]
+; ALL-NEXT: ret i16 [[SEL]]
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 15, %entry ]
+ ret i16 %cond
+}
+
+
+define i64 @test1d(i64 %A) {
+; ALL-LABEL: @test1d(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; ALL-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i64 63, i64 [[CTTZ]]
+; ALL-NEXT: ret i64 [[SEL]]
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 63, %entry ]
+ ret i64 %cond
+}
+
+
+define i32 @test2d(i32 %A) {
+; ALL-LABEL: @test2d(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; ALL-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i32 31, i32 [[CTTZ]]
+; ALL-NEXT: ret i32 [[SEL]]
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 31, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3d(i16 signext %A) {
+; ALL-LABEL: @test3d(
+; ALL: [[ICMP:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; ALL-NEXT: [[CTTZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+; ALL-NEXT: [[SEL:%[A-Za-z0-9.]+]] = select i1 [[ICMP]], i16 15, i16 [[CTTZ]]
+; ALL-NEXT: ret i16 [[SEL]]
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 15, %entry ]
+ ret i16 %cond
+}
+
+
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i16 @llvm.ctlz.i16(i16, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
+declare i16 @llvm.cttz.i16(i16, i1)
diff --git a/test/Transforms/SimplifyCFG/R600/lit.local.cfg b/test/Transforms/SimplifyCFG/R600/lit.local.cfg
new file mode 100644
index 0000000..ad9ce25
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/R600/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'R600' in config.root.targets:
+ config.unsupported = True
diff --git a/test/Transforms/SimplifyCFG/SpeculativeExec.ll b/test/Transforms/SimplifyCFG/SpeculativeExec.ll
index 83fa419..31de3c8 100644
--- a/test/Transforms/SimplifyCFG/SpeculativeExec.ll
+++ b/test/Transforms/SimplifyCFG/SpeculativeExec.ll
@@ -28,22 +28,6 @@ bb3: ; preds = %bb2, %entry
ret i32 %tmp5
}
-declare i8 @llvm.cttz.i8(i8, i1)
-
-define i8 @test2(i8 %a) {
-; CHECK-LABEL: @test2(
- br i1 undef, label %bb_true, label %bb_false
-bb_true:
- %b = tail call i8 @llvm.cttz.i8(i8 %a, i1 false)
- br label %join
-bb_false:
- br label %join
-join:
- %c = phi i8 [%b, %bb_true], [%a, %bb_false]
-; CHECK: select
- ret i8 %c
-}
-
define i8* @test4(i1* %dummy, i8* %a, i8* %b) {
; Test that we don't speculate an arbitrarily large number of unfolded constant
; expressions.
diff --git a/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
index 21428c6..22b144b 100644
--- a/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
+++ b/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
@@ -46,32 +46,6 @@ T:
ret i32 2
}
-; PR9450
-define i32 @test4(i32 %v, i32 %w) {
-; CHECK: entry:
-; CHECK-NEXT: switch i32 %v, label %T [
-; CHECK-NEXT: i32 3, label %V
-; CHECK-NEXT: i32 2, label %U
-; CHECK-NEXT: ]
-
-entry:
- br label %SWITCH
-V:
- ret i32 7
-SWITCH:
- switch i32 %v, label %default [
- i32 1, label %T
- i32 2, label %U
- i32 3, label %V
- ]
-default:
- unreachable
-U:
- ret i32 %w
-T:
- ret i32 2
-}
-
;; We can either convert the following control-flow to a select or remove the
;; unreachable control flow because of the undef store of null. Make sure we do
diff --git a/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll b/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll
new file mode 100644
index 0000000..69f6c69
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/X86/speculate-cttz-ctlz.ll
@@ -0,0 +1,330 @@
+; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+bmi < %s | FileCheck %s --check-prefix=ALL --check-prefix=BMI
+; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+lzcnt < %s | FileCheck %s --check-prefix=ALL --check-prefix=LZCNT
+; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC
+
+
+define i64 @test1(i64 %A) {
+; ALL-LABEL: @test1(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+; LZCNT-NEXT: select i1 [[COND]], i64 64, i64 [[CTLZ]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+define i32 @test2(i32 %A) {
+; ALL-LABEL: @test2(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+; LZCNT-NEXT: select i1 [[COND]], i32 32, i32 [[CTLZ]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3(i16 signext %A) {
+; ALL-LABEL: @test3(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+; LZCNT-NEXT: select i1 [[COND]], i16 16, i16 [[CTLZ]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
+ ret i16 %cond
+}
+
+
+define i64 @test1b(i64 %A) {
+; ALL-LABEL: @test1b(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+; BMI-NEXT: select i1 [[COND]], i64 64, i64 [[CTTZ]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
+ ret i64 %cond
+}
+
+
+define i32 @test2b(i32 %A) {
+; ALL-LABEL: @test2b(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+; BMI-NEXT: select i1 [[COND]], i32 32, i32 [[CTTZ]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
+ ret i32 %cond
+}
+
+
+define signext i16 @test3b(i16 signext %A) {
+; ALL-LABEL: @test3b(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+; BMI-NEXT: select i1 [[COND]], i16 16, i16 [[CTTZ]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i16 %A, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
+ ret i16 %cond
+}
+
+; The following tests verify that calls to cttz/ctlz are speculated even if
+; basic block %cond.true has an extra zero extend/truncate which is "free"
+; for the target.
+
+define i64 @test1e(i32 %x) {
+; ALL-LABEL: @test1e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+; ALL: [[ZEXT:%[A-Za-z0-9]+]] = zext i32 [[CTTZ]] to i64
+; BMI-NEXT: select i1 [[COND]], i64 32, i64 [[ZEXT]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+ %phitmp2 = zext i32 %0 to i64
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %phitmp2, %cond.true ], [ 32, %entry ]
+ ret i64 %cond
+}
+
+define i32 @test2e(i64 %x) {
+; ALL-LABEL: @test2e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTTZ]] to i32
+; BMI-NEXT: select i1 [[COND]], i32 64, i32 [[TRUNC]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i32
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %cast, %cond.true ], [ 64, %entry ]
+ ret i32 %cond
+}
+
+define i64 @test3e(i32 %x) {
+; ALL-LABEL: @test3e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+; ALL: [[ZEXT:%[A-Za-z0-9]+]] = zext i32 [[CTLZ]] to i64
+; LZCNT-NEXT: select i1 [[COND]], i64 32, i64 [[ZEXT]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %phitmp2 = zext i32 %0 to i64
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i64 [ %phitmp2, %cond.true ], [ 32, %entry ]
+ ret i64 %cond
+}
+
+define i32 @test4e(i64 %x) {
+; ALL-LABEL: @test4e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTLZ]] to i32
+; LZCNT-NEXT: select i1 [[COND]], i32 64, i32 [[TRUNC]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i32
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i32 [ %cast, %cond.true ], [ 64, %entry ]
+ ret i32 %cond
+}
+
+define i16 @test5e(i64 %x) {
+; ALL-LABEL: @test5e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTLZ]] to i16
+; LZCNT-NEXT: select i1 [[COND]], i16 64, i16 [[TRUNC]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i16
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %cast, %cond.true ], [ 64, %entry ]
+ ret i16 %cond
+}
+
+define i16 @test6e(i32 %x) {
+; ALL-LABEL: @test6e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
+; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i32 [[CTLZ]] to i16
+; LZCNT-NEXT: select i1 [[COND]], i16 32, i16 [[TRUNC]]
+; BMI-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
+ %cast = trunc i32 %0 to i16
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %cast, %cond.true ], [ 32, %entry ]
+ ret i16 %cond
+}
+
+define i16 @test7e(i64 %x) {
+; ALL-LABEL: @test7e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %x, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i64 [[CTTZ]] to i16
+; BMI-NEXT: select i1 [[COND]], i16 64, i16 [[TRUNC]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i64 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
+ %cast = trunc i64 %0 to i16
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %cast, %cond.true ], [ 64, %entry ]
+ ret i16 %cond
+}
+
+define i16 @test8e(i32 %x) {
+; ALL-LABEL: @test8e(
+; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %x, 0
+; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+; ALL: [[TRUNC:%[A-Za-z0-9]+]] = trunc i32 [[CTTZ]] to i16
+; BMI-NEXT: select i1 [[COND]], i16 32, i16 [[TRUNC]]
+; LZCNT-NOT: select
+; GENERIC-NOT: select
+; ALL: ret
+entry:
+ %tobool = icmp eq i32 %x, 0
+ br i1 %tobool, label %cond.end, label %cond.true
+
+cond.true: ; preds = %entry
+ %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
+ %cast = trunc i32 %0 to i16
+ br label %cond.end
+
+cond.end: ; preds = %entry, %cond.true
+ %cond = phi i16 [ %cast, %cond.true ], [ 32, %entry ]
+ ret i16 %cond
+}
+
+
+declare i64 @llvm.ctlz.i64(i64, i1)
+declare i32 @llvm.ctlz.i32(i32, i1)
+declare i16 @llvm.ctlz.i16(i16, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
+declare i16 @llvm.cttz.i16(i16, i1)
diff --git a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll b/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
index fc22e7e..ea3b575 100644
--- a/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
+++ b/test/Transforms/SimplifyCFG/X86/switch_to_lookup_table.ll
@@ -21,8 +21,8 @@ target triple = "x86_64-unknown-linux-gnu"
; The table for @cprop
; CHECK: @switch.table5 = private unnamed_addr constant [7 x i32] [i32 5, i32 42, i32 126, i32 -452, i32 128, i32 6, i32 7]
-; The table for @unreachable
-; CHECK: @switch.table6 = private unnamed_addr constant [5 x i32] [i32 0, i32 0, i32 0, i32 1, i32 -1]
+; The table for @unreachable_case
+; CHECK: @switch.table6 = private unnamed_addr constant [9 x i32] [i32 0, i32 0, i32 0, i32 2, i32 -1, i32 1, i32 1, i32 1, i32 1]
; A simple int-to-int selection switch.
; It is dense enough to be replaced by table lookup.
@@ -752,7 +752,7 @@ return:
; CHECK: %switch.gep = getelementptr inbounds [7 x i32]* @switch.table5, i32 0, i32 %switch.tableidx
}
-define i32 @unreachable(i32 %x) {
+define i32 @unreachable_case(i32 %x) {
entry:
switch i32 %x, label %sw.default [
i32 0, label %sw.bb
@@ -770,19 +770,47 @@ sw.bb: br label %return
sw.bb1: unreachable
sw.bb2: br label %return
sw.bb3: br label %return
-sw.default: unreachable
+sw.default: br label %return
return:
- %retval.0 = phi i32 [ 1, %sw.bb3 ], [ -1, %sw.bb2 ], [ 0, %sw.bb ]
+ %retval.0 = phi i32 [ 1, %sw.bb3 ], [ -1, %sw.bb2 ], [ 0, %sw.bb ], [ 2, %sw.default ]
ret i32 %retval.0
-; CHECK-LABEL: @unreachable(
+; CHECK-LABEL: @unreachable_case(
; CHECK: switch.lookup:
-; CHECK: getelementptr inbounds [5 x i32]* @switch.table6, i32 0, i32 %switch.tableidx
+; CHECK: getelementptr inbounds [9 x i32]* @switch.table6, i32 0, i32 %switch.tableidx
+}
+
+define i32 @unreachable_default(i32 %x) {
+entry:
+ switch i32 %x, label %default [
+ i32 0, label %bb0
+ i32 1, label %bb1
+ i32 2, label %bb2
+ i32 3, label %bb3
+ ]
+
+bb0: br label %return
+bb1: br label %return
+bb2: br label %return
+bb3: br label %return
+default: unreachable
+
+return:
+ %retval = phi i32 [ 42, %bb0 ], [ 52, %bb1 ], [ 1, %bb2 ], [ 2, %bb3 ]
+ ret i32 %retval
+
+; CHECK-LABEL: @unreachable_default(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0
+; CHECK-NOT: icmp
+; CHECK-NOT: br 1i
+; CHECK-NEXT: %switch.gep = getelementptr inbounds [4 x i32]* @switch.table7, i32 0, i32 %switch.tableidx
+; CHECK-NEXT: %switch.load = load i32* %switch.gep
+; CHECK-NEXT: ret i32 %switch.load
}
; Don't create a table with illegal type
-; rdar://12779436
define i96 @illegaltype(i32 %c) {
entry:
switch i32 %c, label %sw.default [
@@ -1078,3 +1106,170 @@ return:
; CHECK-NEXT: ret i8 %switch.idx.cast
}
+; Reuse the inverted table range compare.
+define i32 @reuse_cmp1(i32 %x) {
+entry:
+ switch i32 %x, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 3, label %sw.bb3
+ ]
+sw.bb: br label %sw.epilog
+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:
+ %r.0 = phi i32 [ 0, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ]
+ %cmp = icmp eq i32 %r.0, 0 ; This compare can be "replaced".
+ br i1 %cmp, label %if.then, label %if.end
+if.then: br label %return
+if.end: br label %return
+return:
+ %retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ]
+ ret i32 %retval.0
+; CHECK-LABEL: @reuse_cmp1(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0
+; CHECK-NEXT: [[C:%.+]] = icmp ult i32 %switch.tableidx, 4
+; CHECK-NEXT: %inverted.cmp = xor i1 [[C]], true
+; CHECK: [[R:%.+]] = select i1 %inverted.cmp, i32 100, i32 {{.*}}
+; CHECK-NEXT: ret i32 [[R]]
+}
+
+; Reuse the table range compare.
+define i32 @reuse_cmp2(i32 %x) {
+entry:
+ switch i32 %x, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 3, label %sw.bb3
+ ]
+sw.bb: br label %sw.epilog
+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:
+ %r.0 = phi i32 [ 4, %sw.default ], [ 3, %sw.bb3 ], [ 2, %sw.bb2 ], [ 1, %sw.bb1 ], [ 0, %sw.bb ]
+ %cmp = icmp ne i32 %r.0, 4 ; This compare can be "replaced".
+ br i1 %cmp, label %if.then, label %if.end
+if.then: br label %return
+if.end: br label %return
+return:
+ %retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
+ ret i32 %retval.0
+; CHECK-LABEL: @reuse_cmp2(
+; CHECK: entry:
+; CHECK-NEXT: %switch.tableidx = sub i32 %x, 0
+; CHECK-NEXT: [[C:%.+]] = icmp ult i32 %switch.tableidx, 4
+; CHECK: [[R:%.+]] = select i1 [[C]], i32 {{.*}}, i32 100
+; CHECK-NEXT: ret i32 [[R]]
+}
+
+; Cannot reuse the table range compare, because the default value is the same
+; as one of the case values.
+define i32 @no_reuse_cmp(i32 %x) {
+entry:
+ switch i32 %x, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 3, label %sw.bb3
+ ]
+sw.bb: br label %sw.epilog
+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:
+ %r.0 = phi i32 [ 12, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ]
+ %cmp = icmp ne i32 %r.0, 0
+ br i1 %cmp, label %if.then, label %if.end
+if.then: br label %return
+if.end: br label %return
+return:
+ %retval.0 = phi i32 [ %r.0, %if.then ], [ 100, %if.end ]
+ ret i32 %retval.0
+; CHECK-LABEL: @no_reuse_cmp(
+; CHECK: [[S:%.+]] = select
+; CHECK-NEXT: %cmp = icmp ne i32 [[S]], 0
+; CHECK-NEXT: [[R:%.+]] = select i1 %cmp, i32 [[S]], i32 100
+; CHECK-NEXT: ret i32 [[R]]
+}
+
+; Cannot reuse the table range compare, because the phi at the switch merge
+; point is not dominated by the switch.
+define i32 @no_reuse_cmp2(i32 %x, i32 %y) {
+entry:
+ %ec = icmp ne i32 %y, 0
+ br i1 %ec, label %switch.entry, label %sw.epilog
+switch.entry:
+ switch i32 %x, label %sw.default [
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 3, label %sw.bb3
+ ]
+sw.bb: br label %sw.epilog
+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:
+ %r.0 = phi i32 [100, %entry], [ 0, %sw.default ], [ 13, %sw.bb3 ], [ 12, %sw.bb2 ], [ 11, %sw.bb1 ], [ 10, %sw.bb ]
+ %cmp = icmp eq i32 %r.0, 0 ; This compare can be "replaced".
+ br i1 %cmp, label %if.then, label %if.end
+if.then: br label %return
+if.end: br label %return
+return:
+ %retval.0 = phi i32 [ 100, %if.then ], [ %r.0, %if.end ]
+ ret i32 %retval.0
+; CHECK-LABEL: @no_reuse_cmp2(
+; CHECK: %r.0 = phi
+; CHECK-NEXT: %cmp = icmp eq i32 %r.0, 0
+; CHECK-NEXT: [[R:%.+]] = select i1 %cmp
+; CHECK-NEXT: ret i32 [[R]]
+}
+
+define void @pr20210(i8 %x, i1 %y) {
+; %z has uses outside of its BB or the phi it feeds into,
+; so doing a table lookup and jumping directly to while.cond would
+; cause %z to cease dominating all its uses.
+
+entry:
+ br i1 %y, label %sw, label %intermediate
+
+sw:
+ switch i8 %x, label %end [
+ i8 7, label %intermediate
+ i8 3, label %intermediate
+ i8 2, label %intermediate
+ i8 1, label %intermediate
+ i8 0, label %intermediate
+ ]
+
+intermediate:
+ %z = zext i8 %x to i32
+ br label %while.cond
+
+while.cond:
+ %i = phi i32 [ %z, %intermediate ], [ %j, %while.body ]
+ %b = icmp ne i32 %i, 7
+ br i1 %b, label %while.body, label %while.end
+
+while.body:
+ %j = add i32 %i, 1
+ br label %while.cond
+
+while.end:
+ call void @exit(i32 %z)
+ unreachable
+
+end:
+ ret void
+; CHECK-LABEL: @pr20210
+; CHECK: switch i8 %x
+}
diff --git a/test/Transforms/SimplifyCFG/basictest.ll b/test/Transforms/SimplifyCFG/basictest.ll
index d6958a9..5d9dad4 100644
--- a/test/Transforms/SimplifyCFG/basictest.ll
+++ b/test/Transforms/SimplifyCFG/basictest.ll
@@ -1,6 +1,7 @@
; Test CFG simplify removal of branch instructions.
;
; RUN: opt < %s -simplifycfg -S | FileCheck %s
+; RUN: opt < %s -passes=simplify-cfg -S | FileCheck %s
define void @test1() {
br label %1
@@ -68,6 +69,6 @@ bb3:
}
declare i8 @test6g(i8*)
-!0 = metadata !{metadata !1, metadata !1, i64 0}
-!1 = metadata !{metadata !"foo"}
-!2 = metadata !{i8 0, i8 2}
+!0 = !{!1, !1, i64 0}
+!1 = !{!"foo"}
+!2 = !{i8 0, i8 2}
diff --git a/test/Transforms/SimplifyCFG/branch-fold-dbg.ll b/test/Transforms/SimplifyCFG/branch-fold-dbg.ll
index 9235f62..f715a0c 100644
--- a/test/Transforms/SimplifyCFG/branch-fold-dbg.ll
+++ b/test/Transforms/SimplifyCFG/branch-fold-dbg.ll
@@ -25,7 +25,7 @@ BB2: ; preds = %BB1
BB3: ; preds = %BB2
%6 = getelementptr inbounds [5 x %0]* @0, i32 0, i32 %0, !dbg !6
- call void @llvm.dbg.value(metadata !{%0* %6}, i64 0, metadata !7, metadata !{}), !dbg !12
+ call void @llvm.dbg.value(metadata %0* %6, i64 0, metadata !7, metadata !{}), !dbg !12
%7 = icmp eq %0* %6, null, !dbg !13
br i1 %7, label %BB5, label %BB4, !dbg !13
@@ -41,19 +41,19 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.sp = !{!0}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00\00231\000\001\000\006\00256\000\000", metadata !15, metadata !1, metadata !3, null, void (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 231] [def] [scope 0] [foo]
-!1 = metadata !{metadata !"0x29", metadata !15} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00clang (trunk 129006)\001\00\000\00\000", metadata !15, metadata !4, metadata !4, null, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !15, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{null}
-!5 = metadata !{i32 131, i32 2, metadata !0, null}
-!6 = metadata !{i32 134, i32 2, metadata !0, null}
-!7 = metadata !{metadata !"0x100\00bar\00232\000", metadata !8, metadata !1, metadata !9} ; [ DW_TAG_auto_variable ]
-!8 = metadata !{metadata !"0xb\00231\001\003", metadata !15, metadata !0} ; [ DW_TAG_lexical_block ]
-!9 = metadata !{metadata !"0xf\00\000\0032\0032\000\000", null, metadata !2, metadata !10} ; [ DW_TAG_pointer_type ]
-!10 = metadata !{metadata !"0x26\00\000\000\000\000\000", null, metadata !2, metadata !11} ; [ DW_TAG_const_type ]
-!11 = metadata !{metadata !"0x24\00unsigned int\000\0032\0032\000\000\007", null, metadata !2} ; [ DW_TAG_base_type ]
-!12 = metadata !{i32 232, i32 40, metadata !8, null}
-!13 = metadata !{i32 234, i32 2, metadata !8, null}
-!14 = metadata !{i32 274, i32 1, metadata !8, null}
-!15 = metadata !{metadata !"a.c", metadata !"/private/tmp"}
+!0 = !{!"0x2e\00foo\00foo\00\00231\000\001\000\006\00256\000\000", !15, !1, !3, null, void (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 231] [def] [scope 0] [foo]
+!1 = !{!"0x29", !15} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00clang (trunk 129006)\001\00\000\00\000", !15, !4, !4, null, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !15, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{null}
+!5 = !MDLocation(line: 131, column: 2, scope: !0)
+!6 = !MDLocation(line: 134, column: 2, scope: !0)
+!7 = !{!"0x100\00bar\00232\000", !8, !1, !9} ; [ DW_TAG_auto_variable ]
+!8 = !{!"0xb\00231\001\003", !15, !0} ; [ DW_TAG_lexical_block ]
+!9 = !{!"0xf\00\000\0032\0032\000\000", null, !2, !10} ; [ DW_TAG_pointer_type ]
+!10 = !{!"0x26\00\000\000\000\000\000", null, !2, !11} ; [ DW_TAG_const_type ]
+!11 = !{!"0x24\00unsigned int\000\0032\0032\000\000\007", null, !2} ; [ DW_TAG_base_type ]
+!12 = !MDLocation(line: 232, column: 40, scope: !8)
+!13 = !MDLocation(line: 234, column: 2, scope: !8)
+!14 = !MDLocation(line: 274, column: 1, scope: !8)
+!15 = !{!"a.c", !"/private/tmp"}
diff --git a/test/Transforms/SimplifyCFG/clamp.ll b/test/Transforms/SimplifyCFG/clamp.ll
new file mode 100644
index 0000000..d21894a
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/clamp.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
+
+define float @clamp(float %a, float %b, float %c) {
+; CHECK-LABEL: @clamp
+; CHECK: %cmp = fcmp ogt float %a, %c
+; CHECK: %cmp1 = fcmp olt float %a, %b
+; CHECK: %cond = select i1 %cmp1, float %b, float %a
+; CHECK: %cond5 = select i1 %cmp, float %c, float %cond
+; CHECK: ret float %cond5
+entry:
+ %cmp = fcmp ogt float %a, %c
+ br i1 %cmp, label %cond.end4, label %cond.false
+
+cond.false: ; preds = %entry
+ %cmp1 = fcmp olt float %a, %b
+ %cond = select i1 %cmp1, float %b, float %a
+ br label %cond.end4
+
+cond.end4: ; preds = %entry, %cond.false
+ %cond5 = phi float [ %cond, %cond.false ], [ %c, %entry ]
+ ret float %cond5
+}
diff --git a/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll b/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll
index cc382be..869ce09 100644
--- a/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll
+++ b/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll
@@ -1,8 +1,8 @@
; RUN: opt -simplifycfg -S < %s | FileCheck %s
define i32 @foo(i32 %i) nounwind ssp {
- call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !6, metadata !{}), !dbg !7
- call void @llvm.dbg.value(metadata !8, i64 0, metadata !9, metadata !{}), !dbg !11
+ call void @llvm.dbg.value(metadata i32 %i, i64 0, metadata !6, metadata !{}), !dbg !7
+ call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !9, metadata !{}), !dbg !11
%1 = icmp ne i32 %i, 0, !dbg !12
;CHECK: call i32 (...)* @bar()
;CHECK-NEXT: llvm.dbg.value
@@ -10,12 +10,12 @@ define i32 @foo(i32 %i) nounwind ssp {
; <label>:2 ; preds = %0
%3 = call i32 (...)* @bar(), !dbg !13
- call void @llvm.dbg.value(metadata !{i32 %3}, i64 0, metadata !9, metadata !{}), !dbg !13
+ call void @llvm.dbg.value(metadata i32 %3, i64 0, metadata !9, metadata !{}), !dbg !13
br label %6, !dbg !15
; <label>:4 ; preds = %0
%5 = call i32 (...)* @bar(), !dbg !16
- call void @llvm.dbg.value(metadata !{i32 %5}, i64 0, metadata !9, metadata !{}), !dbg !16
+ call void @llvm.dbg.value(metadata i32 %5, i64 0, metadata !9, metadata !{}), !dbg !16
br label %6, !dbg !18
; <label>:6 ; preds = %4, %2
@@ -32,25 +32,25 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.module.flags = !{!21}
!llvm.dbg.sp = !{!0}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00\002\000\001\000\006\00256\000\000", metadata !20, metadata !1, metadata !3, null, i32 (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 2] [def] [scope 0] [foo]
-!1 = metadata !{metadata !"0x29", metadata !20} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00clang\001\00\000\00\000", metadata !20, metadata !8, metadata !8, null, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !20, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{metadata !5}
-!5 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, metadata !2} ; [ DW_TAG_base_type ]
-!6 = metadata !{metadata !"0x101\00i\0016777218\000", metadata !0, metadata !1, metadata !5} ; [ DW_TAG_arg_variable ]
-!7 = metadata !{i32 2, i32 13, metadata !0, null}
-!8 = metadata !{i32 0}
-!9 = metadata !{metadata !"0x100\00k\003\000", metadata !10, metadata !1, metadata !5} ; [ DW_TAG_auto_variable ]
-!10 = metadata !{metadata !"0xb\002\0016\000", metadata !20, metadata !0} ; [ DW_TAG_lexical_block ]
-!11 = metadata !{i32 3, i32 12, metadata !10, null}
-!12 = metadata !{i32 4, i32 3, metadata !10, null}
-!13 = metadata !{i32 5, i32 5, metadata !14, null}
-!14 = metadata !{metadata !"0xb\004\0010\001", metadata !20, metadata !10} ; [ DW_TAG_lexical_block ]
-!15 = metadata !{i32 6, i32 3, metadata !14, null}
-!16 = metadata !{i32 7, i32 5, metadata !17, null}
-!17 = metadata !{metadata !"0xb\006\0010\002", metadata !20, metadata !10} ; [ DW_TAG_lexical_block ]
-!18 = metadata !{i32 8, i32 3, metadata !17, null}
-!19 = metadata !{i32 9, i32 3, metadata !10, null}
-!20 = metadata !{metadata !"b.c", metadata !"/private/tmp"}
-!21 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00foo\00foo\00\002\000\001\000\006\00256\000\000", !20, !1, !3, null, i32 (i32)* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 2] [def] [scope 0] [foo]
+!1 = !{!"0x29", !20} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00clang\001\00\000\00\000", !20, !8, !8, null, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !20, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{!5}
+!5 = !{!"0x24\00int\000\0032\0032\000\000\005", null, !2} ; [ DW_TAG_base_type ]
+!6 = !{!"0x101\00i\0016777218\000", !0, !1, !5} ; [ DW_TAG_arg_variable ]
+!7 = !MDLocation(line: 2, column: 13, scope: !0)
+!8 = !{i32 0}
+!9 = !{!"0x100\00k\003\000", !10, !1, !5} ; [ DW_TAG_auto_variable ]
+!10 = !{!"0xb\002\0016\000", !20, !0} ; [ DW_TAG_lexical_block ]
+!11 = !MDLocation(line: 3, column: 12, scope: !10)
+!12 = !MDLocation(line: 4, column: 3, scope: !10)
+!13 = !MDLocation(line: 5, column: 5, scope: !14)
+!14 = !{!"0xb\004\0010\001", !20, !10} ; [ DW_TAG_lexical_block ]
+!15 = !MDLocation(line: 6, column: 3, scope: !14)
+!16 = !MDLocation(line: 7, column: 5, scope: !17)
+!17 = !{!"0xb\006\0010\002", !20, !10} ; [ DW_TAG_lexical_block ]
+!18 = !MDLocation(line: 8, column: 3, scope: !17)
+!19 = !MDLocation(line: 9, column: 3, scope: !10)
+!20 = !{!"b.c", !"/private/tmp"}
+!21 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/SimplifyCFG/hoist-with-range.ll b/test/Transforms/SimplifyCFG/hoist-with-range.ll
index 362aa9a..7ca3ff2 100644
--- a/test/Transforms/SimplifyCFG/hoist-with-range.ll
+++ b/test/Transforms/SimplifyCFG/hoist-with-range.ll
@@ -3,7 +3,7 @@
define void @foo(i1 %c, i8* %p) {
; CHECK: if:
; CHECK-NEXT: load i8* %p, !range !0
-; CHECK: !0 = metadata !{i8 0, i8 1, i8 3, i8 5}
+; CHECK: !0 = !{i8 0, i8 1, i8 3, i8 5}
if:
br i1 %c, label %then, label %else
then:
@@ -16,5 +16,5 @@ out:
ret void
}
-!0 = metadata !{ i8 0, i8 1 }
-!1 = metadata !{ i8 3, i8 5 }
+!0 = !{ i8 0, i8 1 }
+!1 = !{ i8 3, i8 5 }
diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll b/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll
index 8cc07e3..b2b3841 100644
--- a/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll
+++ b/test/Transforms/SimplifyCFG/preserve-branchweights-partial.ll
@@ -34,4 +34,4 @@ if.end:
ret void
}
-!0 = metadata !{metadata !"branch_weights", i32 1, i32 0}
+!0 = !{!"branch_weights", i32 1, i32 0}
diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll b/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll
index 941f5ad..32a30c3 100644
--- a/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll
+++ b/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll
@@ -129,12 +129,12 @@ sw.epilog:
ret void
}
-!0 = metadata !{metadata !"branch_weights", i32 64, i32 4}
-!1 = metadata !{metadata !"branch_weights", i32 4, i32 64}
-; CHECK: !0 = metadata !{metadata !"branch_weights", i32 256, i32 4352, i32 16}
-!2 = metadata !{metadata !"branch_weights", i32 4, i32 4, i32 8}
-!3 = metadata !{metadata !"branch_weights", i32 8, i32 8, i32 4}
-; CHECK: !1 = metadata !{metadata !"branch_weights", i32 32, i32 48, i32 96, i32 16}
-!4 = metadata !{metadata !"branch_weights", i32 7, i32 6, i32 4, i32 3}
-!5 = metadata !{metadata !"branch_weights", i32 17, i32 13, i32 9}
-; CHECK: !3 = metadata !{metadata !"branch_weights", i32 7, i32 3, i32 4, i32 6}
+!0 = !{!"branch_weights", i32 64, i32 4}
+!1 = !{!"branch_weights", i32 4, i32 64}
+; CHECK: !0 = !{!"branch_weights", i32 256, i32 4352, i32 16}
+!2 = !{!"branch_weights", i32 4, i32 4, i32 8}
+!3 = !{!"branch_weights", i32 8, i32 8, i32 4}
+; CHECK: !1 = !{!"branch_weights", i32 32, i32 48, i32 96, i32 16}
+!4 = !{!"branch_weights", i32 7, i32 6, i32 4, i32 3}
+!5 = !{!"branch_weights", i32 17, i32 13, i32 9}
+; CHECK: !3 = !{!"branch_weights", i32 7, i32 3, i32 4, i32 6}
diff --git a/test/Transforms/SimplifyCFG/preserve-branchweights.ll b/test/Transforms/SimplifyCFG/preserve-branchweights.ll
index bdd25ba..7802a05 100644
--- a/test/Transforms/SimplifyCFG/preserve-branchweights.ll
+++ b/test/Transforms/SimplifyCFG/preserve-branchweights.ll
@@ -364,29 +364,29 @@ 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}
-!3 = metadata !{metadata !"branch_weights", i32 4, i32 3, i32 2, i32 1}
-!4 = metadata !{metadata !"branch_weights", i32 4, i32 3, i32 2, i32 1}
-!5 = metadata !{metadata !"branch_weights", i32 7, i32 6, i32 5}
-!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}
-; CHECK: !2 = metadata !{metadata !"branch_weights", i32 7, i32 1, i32 2}
-; CHECK: !3 = metadata !{metadata !"branch_weights", i32 49, i32 12, i32 24, i32 35}
-; CHECK: !4 = metadata !{metadata !"branch_weights", i32 11, i32 5}
-; CHECK: !5 = metadata !{metadata !"branch_weights", i32 17, i32 15}
-; CHECK: !6 = metadata !{metadata !"branch_weights", i32 9, i32 7}
-; 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}
+!0 = !{!"branch_weights", i32 3, i32 5}
+!1 = !{!"branch_weights", i32 1, i32 1}
+!2 = !{!"branch_weights", i32 1, i32 2}
+!3 = !{!"branch_weights", i32 4, i32 3, i32 2, i32 1}
+!4 = !{!"branch_weights", i32 4, i32 3, i32 2, i32 1}
+!5 = !{!"branch_weights", i32 7, i32 6, i32 5}
+!6 = !{!"branch_weights", i32 1, i32 3}
+!7 = !{!"branch_weights", i32 33, i32 9, i32 8, i32 7}
+!8 = !{!"branch_weights", i32 33, i32 9, i32 8}
+!9 = !{!"branch_weights", i32 7, i32 6}
+!10 = !{!"branch_weights", i32 672646, i32 21604207}
+!11 = !{!"branch_weights", i32 6960, i32 21597248}
+
+; CHECK: !0 = !{!"branch_weights", i32 5, i32 11}
+; CHECK: !1 = !{!"branch_weights", i32 1, i32 5}
+; CHECK: !2 = !{!"branch_weights", i32 7, i32 1, i32 2}
+; CHECK: !3 = !{!"branch_weights", i32 49, i32 12, i32 24, i32 35}
+; CHECK: !4 = !{!"branch_weights", i32 11, i32 5}
+; CHECK: !5 = !{!"branch_weights", i32 17, i32 15}
+; CHECK: !6 = !{!"branch_weights", i32 9, i32 7}
+; CHECK: !7 = !{!"branch_weights", i32 17, i32 9, i32 8, i32 7, i32 17}
+; CHECK: !8 = !{!"branch_weights", i32 24, i32 33}
+; CHECK: !9 = !{!"branch_weights", i32 8, i32 33}
;; 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}
+; CHECK: !10 = !{!"branch_weights", i32 112017436, i32 -735157296}
diff --git a/test/Transforms/SimplifyCFG/seh-nounwind.ll b/test/Transforms/SimplifyCFG/seh-nounwind.ll
new file mode 100644
index 0000000..3845e31
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/seh-nounwind.ll
@@ -0,0 +1,31 @@
+; RUN: opt -S -simplifycfg < %s | FileCheck %s
+
+; Don't remove invokes of nounwind functions if the personality handles async
+; exceptions. The @div function in this test can fault, even though it can't
+; throw a synchronous exception.
+
+define i32 @div(i32 %n, i32 %d) nounwind {
+entry:
+ %div = sdiv i32 %n, %d
+ ret i32 %div
+}
+
+define i32 @main() nounwind {
+entry:
+ %call = invoke i32 @div(i32 10, i32 0)
+ to label %__try.cont unwind label %lpad
+
+lpad:
+ %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+ catch i8* null
+ br label %__try.cont
+
+__try.cont:
+ %retval.0 = phi i32 [ %call, %entry ], [ 0, %lpad ]
+ ret i32 %retval.0
+}
+
+; CHECK-LABEL: define i32 @main()
+; CHECK: invoke i32 @div(i32 10, i32 0)
+
+declare i32 @__C_specific_handler(...)
diff --git a/test/Transforms/SimplifyCFG/select-gep.ll b/test/Transforms/SimplifyCFG/select-gep.ll
index 96c214c..43e46ca 100644
--- a/test/Transforms/SimplifyCFG/select-gep.ll
+++ b/test/Transforms/SimplifyCFG/select-gep.ll
@@ -1,27 +1,8 @@
; RUN: opt -S -simplifycfg < %s | FileCheck %s
-define i8* @test1(i8* %x, i64 %y) nounwind {
-entry:
- %tmp1 = load i8* %x, align 1
- %cmp = icmp eq i8 %tmp1, 47
- br i1 %cmp, label %if.then, label %if.end
-
-if.then:
- %incdec.ptr = getelementptr inbounds i8* %x, i64 %y
- br label %if.end
-
-if.end:
- %x.addr = phi i8* [ %incdec.ptr, %if.then ], [ %x, %entry ]
- ret i8* %x.addr
-
-; CHECK-LABEL: @test1(
-; CHECK-NOT: select
-; CHECK: ret i8* %x.addr
-}
-
%ST = type { i8, i8 }
-define i8* @test2(%ST* %x, i8* %y) nounwind {
+define i8* @test1(%ST* %x, i8* %y) nounwind {
entry:
%cmp = icmp eq %ST* %x, null
br i1 %cmp, label %if.then, label %if.end
@@ -34,7 +15,7 @@ if.end:
%x.addr = phi i8* [ %incdec.ptr, %if.then ], [ %y, %entry ]
ret i8* %x.addr
-; CHECK-LABEL: @test2(
+; CHECK-LABEL: @test1(
; CHECK: %incdec.ptr.y = select i1 %cmp, i8* %incdec.ptr, i8* %y
; CHECK: ret i8* %incdec.ptr.y
}
diff --git a/test/Transforms/SimplifyCFG/sink-common-code.ll b/test/Transforms/SimplifyCFG/sink-common-code.ll
index 28d7279..cdb6ed2 100644
--- a/test/Transforms/SimplifyCFG/sink-common-code.ll
+++ b/test/Transforms/SimplifyCFG/sink-common-code.ll
@@ -4,7 +4,7 @@ define zeroext i1 @test1(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
entry:
br i1 %flag, label %if.then, label %if.else
-; CHECK: test1
+; CHECK-LABEL: test1
; CHECK: add
; CHECK: select
; CHECK: icmp
@@ -30,7 +30,7 @@ define zeroext i1 @test2(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
entry:
br i1 %flag, label %if.then, label %if.else
-; CHECK: test2
+; CHECK-LABEL: test2
; CHECK: add
; CHECK: select
; CHECK: icmp
@@ -51,3 +51,33 @@ if.end:
%tobool4 = icmp ne i8 %obeys.0, 0
ret i1 %tobool4
}
+
+declare i32 @foo(i32, i32) nounwind readnone
+
+define i32 @test3(i1 zeroext %flag, i32 %x, i32 %y) {
+entry:
+ br i1 %flag, label %if.then, label %if.else
+
+if.then:
+ %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
+ %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
+ br label %if.end
+
+if.else:
+ %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
+ %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
+ br label %if.end
+
+if.end:
+ %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
+ %yy = phi i32 [ %y0, %if.then ], [ %y1, %if.else ]
+ %ret = add i32 %xx, %yy
+ ret i32 %ret
+}
+
+; CHECK-LABEL: test3
+; CHECK: select
+; CHECK: call
+; CHECK: call
+; CHECK: add
+; CHECK-NOT: br
diff --git a/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll b/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
new file mode 100644
index 0000000..a109b31
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll
@@ -0,0 +1,77 @@
+; RUN: opt %s -simplifycfg -S | FileCheck %s
+
+declare i32 @f(i32)
+
+define i32 @basic(i32 %x) {
+; CHECK-LABEL: @basic
+; CHECK: x.off = add i32 %x, -5
+; CHECK: %switch = icmp ult i32 %x.off, 3
+; CHECK: br i1 %switch, label %a, label %default
+
+entry:
+ switch i32 %x, label %default [
+ i32 5, label %a
+ i32 6, label %a
+ i32 7, label %a
+ ]
+default:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+a:
+ %1 = call i32 @f(i32 1)
+ ret i32 %1
+}
+
+
+define i32 @unreachable(i32 %x) {
+; CHECK-LABEL: @unreachable
+; CHECK: x.off = add i32 %x, -5
+; CHECK: %switch = icmp ult i32 %x.off, 3
+; CHECK: br i1 %switch, label %a, label %b
+
+entry:
+ switch i32 %x, label %unreachable [
+ i32 5, label %a
+ i32 6, label %a
+ i32 7, label %a
+ i32 10, label %b
+ i32 20, label %b
+ i32 30, label %b
+ i32 40, label %b
+ ]
+unreachable:
+ unreachable
+a:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+b:
+ %1 = call i32 @f(i32 1)
+ ret i32 %1
+}
+
+
+define i32 @unreachable2(i32 %x) {
+; CHECK-LABEL: @unreachable2
+; CHECK: x.off = add i32 %x, -5
+; CHECK: %switch = icmp ult i32 %x.off, 3
+; CHECK: br i1 %switch, label %a, label %b
+
+entry:
+ ; Note: folding the most popular case destination into the default
+ ; would prevent switch-to-icmp here.
+ switch i32 %x, label %unreachable [
+ i32 5, label %a
+ i32 6, label %a
+ i32 7, label %a
+ i32 10, label %b
+ i32 20, label %b
+ ]
+unreachable:
+ unreachable
+a:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+b:
+ %1 = call i32 @f(i32 1)
+ ret i32 %1
+}
diff --git a/test/Transforms/SimplifyCFG/switch-to-br.ll b/test/Transforms/SimplifyCFG/switch-to-br.ll
new file mode 100644
index 0000000..01484cd
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/switch-to-br.ll
@@ -0,0 +1,64 @@
+; RUN: opt %s -simplifycfg -S | FileCheck %s
+
+declare i32 @f(i32)
+
+define i32 @basic(i32 %x) {
+; CHECK-LABEL: @basic
+; CHECK-LABEL: entry:
+; CHECK-NEXT: call i32 @f(i32 0)
+; CHECK-NEXT: ret i32 %0
+
+entry:
+ switch i32 %x, label %default [
+ i32 5, label %default
+ i32 6, label %default
+ i32 7, label %default
+ ]
+default:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+}
+
+
+define i32 @constant() {
+; CHECK-LABEL: @constant
+; CHECK-LABEL: entry:
+; CHECK-NEXT: call i32 @f(i32 1)
+; CHECK-NEXT: ret i32 %0
+
+entry:
+ switch i32 42, label %default [
+ i32 41, label %default
+ i32 42, label %a
+ i32 43, label %b
+ ]
+default:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+a:
+ %1 = call i32 @f(i32 1)
+ ret i32 %1
+b:
+ %2 = call i32 @f(i32 2)
+ ret i32 %2
+}
+
+
+define i32 @unreachable(i32 %x) {
+; CHECK-LABEL: @unreachable
+; CHECK-LABEL: entry:
+; CHECK-NEXT: call i32 @f(i32 0)
+; CHECK-NEXT: ret i32 %0
+
+entry:
+ switch i32 %x, label %unreachable [
+ i32 5, label %a
+ i32 6, label %a
+ i32 7, label %a
+ ]
+unreachable:
+ unreachable
+a:
+ %0 = call i32 @f(i32 0)
+ ret i32 %0
+}
diff --git a/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll b/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
index 69f97e5..f4d171a 100644
--- a/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
+++ b/test/Transforms/SimplifyCFG/switch-to-select-two-case.ll
@@ -35,38 +35,3 @@ return:
%retval.0 = phi i32 [ 4, %sw.epilog ], [ 2, %sw.bb1 ], [ 10, %sw.bb ]
ret i32 %retval.0
}
-
-; int foo1_without_default(int a) {
-; switch(a) {
-; case 10:
-; return 10;
-; case 20:
-; return 2;
-; }
-; __builtin_unreachable();
-; }
-
-define i32 @foo1_without_default(i32 %a) {
-; CHECK-LABEL: @foo1_without_default
-; CHECK: %switch.selectcmp = icmp eq i32 %a, 10
-; CHECK-NEXT: %switch.select = select i1 %switch.selectcmp, i32 10, i32 2
-; CHECK-NOT: %switch.selectcmp1
-entry:
- switch i32 %a, label %sw.epilog [
- i32 10, label %sw.bb
- i32 20, label %sw.bb1
- ]
-
-sw.bb:
- br label %return
-
-sw.bb1:
- br label %return
-
-sw.epilog:
- unreachable
-
-return:
- %retval.0 = phi i32 [ 2, %sw.bb1 ], [ 10, %sw.bb ]
- ret i32 %retval.0
-}
diff --git a/test/Transforms/SimplifyCFG/trap-debugloc.ll b/test/Transforms/SimplifyCFG/trap-debugloc.ll
index adf4215..24a286f 100644
--- a/test/Transforms/SimplifyCFG/trap-debugloc.ll
+++ b/test/Transforms/SimplifyCFG/trap-debugloc.ll
@@ -11,14 +11,14 @@ define void @foo() nounwind ssp {
!llvm.module.flags = !{!10}
!llvm.dbg.sp = !{!0}
-!0 = metadata !{metadata !"0x2e\00foo\00foo\00\003\000\001\000\006\000\000\000", metadata !8, metadata !1, metadata !3, null, void ()* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 3] [def] [scope 0] [foo]
-!1 = metadata !{metadata !"0x29", metadata !8} ; [ DW_TAG_file_type ]
-!2 = metadata !{metadata !"0x11\0012\00Apple clang version 3.0 (tags/Apple/clang-206.1) (based on LLVM 3.0svn)\001\00\000\00\000", metadata !8, metadata !4, metadata !4, metadata !9, null, null} ; [ DW_TAG_compile_unit ]
-!3 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", metadata !8, metadata !1, null, metadata !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
-!4 = metadata !{null}
-!5 = metadata !{i32 4, i32 2, metadata !6, null}
-!6 = metadata !{metadata !"0xb\003\0012\000", metadata !8, metadata !0} ; [ DW_TAG_lexical_block ]
-!7 = metadata !{i32 5, i32 1, metadata !6, null}
-!8 = metadata !{metadata !"foo.c", metadata !"/private/tmp"}
-!9 = metadata !{metadata !0}
-!10 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
+!0 = !{!"0x2e\00foo\00foo\00\003\000\001\000\006\000\000\000", !8, !1, !3, null, void ()* @foo, null, null, null} ; [ DW_TAG_subprogram ] [line 3] [def] [scope 0] [foo]
+!1 = !{!"0x29", !8} ; [ DW_TAG_file_type ]
+!2 = !{!"0x11\0012\00Apple clang version 3.0 (tags/Apple/clang-206.1) (based on LLVM 3.0svn)\001\00\000\00\000", !8, !4, !4, !9, null, null} ; [ DW_TAG_compile_unit ]
+!3 = !{!"0x15\00\000\000\000\000\000\000", !8, !1, null, !4, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!4 = !{null}
+!5 = !MDLocation(line: 4, column: 2, scope: !6)
+!6 = !{!"0xb\003\0012\000", !8, !0} ; [ DW_TAG_lexical_block ]
+!7 = !MDLocation(line: 5, column: 1, scope: !6)
+!8 = !{!"foo.c", !"/private/tmp"}
+!9 = !{!0}
+!10 = !{i32 1, !"Debug Info Version", i32 2}
diff --git a/test/Transforms/SimplifyCFG/trivial-throw.ll b/test/Transforms/SimplifyCFG/trivial-throw.ll
deleted file mode 100644
index ca2b569..0000000
--- a/test/Transforms/SimplifyCFG/trivial-throw.ll
+++ /dev/null
@@ -1,77 +0,0 @@
-; RUN: opt -simplifycfg -S < %s | FileCheck %s
-; <rdar://problem/13360379>
-
-@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
-@_ZTS13TestException = linkonce_odr constant [16 x i8] c"13TestException\00"
-@_ZTI13TestException = linkonce_odr unnamed_addr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([16 x i8]* @_ZTS13TestException, i32 0, i32 0) }
-
-define void @throw(i32 %n) #0 {
-entry:
- %exception = call i8* @__cxa_allocate_exception(i64 1) #4
- call void @__cxa_throw(i8* %exception, i8* bitcast ({ i8*, i8* }* @_ZTI13TestException to i8*), i8* null) #2
- unreachable
-}
-
-define void @func() #0 {
-entry:
-; CHECK: func()
-; CHECK: invoke void @throw
-; CHECK-NOT: call void @throw
- invoke void @throw(i32 42) #0
- to label %exit unwind label %lpad
-
-lpad:
- %tmp0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
- cleanup
- resume { i8*, i32 } %tmp0
-
-exit:
- invoke void @abort() #2
- to label %invoke.cont unwind label %lpad1
-
-invoke.cont:
- unreachable
-
-lpad1:
- %tmp1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
- catch i8* bitcast ({ i8*, i8* }* @_ZTI13TestException to i8*)
- %tmp2 = extractvalue { i8*, i32 } %tmp1, 1
- %tmp3 = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI13TestException to i8*)) #4
- %matches = icmp eq i32 %tmp2, %tmp3
- br i1 %matches, label %catch, label %eh.resume
-
-catch:
- ret void
-
-eh.resume:
- resume { i8*, i32 } %tmp1
-}
-
-define linkonce_odr hidden void @__clang_call_terminate(i8*) #1 {
- %2 = call i8* @__cxa_begin_catch(i8* %0) #4
- call void @_ZSt9terminatev() #5
- unreachable
-}
-
-declare void @abort() #2
-
-declare i32 @llvm.eh.typeid.for(i8*) #3
-
-declare void @__cxa_end_catch()
-
-declare i8* @__cxa_allocate_exception(i64)
-
-declare i32 @__gxx_personality_v0(...)
-
-declare void @__cxa_throw(i8*, i8*, i8*)
-
-declare i8* @__cxa_begin_catch(i8*)
-
-declare void @_ZSt9terminatev()
-
-attributes #0 = { ssp uwtable }
-attributes #1 = { noinline noreturn nounwind }
-attributes #2 = { noreturn }
-attributes #3 = { nounwind readnone }
-attributes #4 = { nounwind }
-attributes #5 = { noreturn nounwind }
diff --git a/test/Transforms/SimplifyCFG/volatile-phioper.ll b/test/Transforms/SimplifyCFG/volatile-phioper.ll
index 1ef3a7c..6367451 100644
--- a/test/Transforms/SimplifyCFG/volatile-phioper.ll
+++ b/test/Transforms/SimplifyCFG/volatile-phioper.ll
@@ -45,4 +45,4 @@ attributes #0 = { nounwind ssp uwtable "fp-contract-model"="standard" "no-frame-
attributes #1 = { "fp-contract-model"="standard" "no-frame-pointer-elim" "no-frame-pointer-elim-non-leaf" "relocation-model"="pic" "ssp-buffers-size"="8" }
attributes #2 = { nounwind }
-!0 = metadata !{i32 1039}
+!0 = !{i32 1039}