summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorGerolf Hoflehner <ghoflehner@apple.com>2014-10-01 00:13:22 +0000
committerGerolf Hoflehner <ghoflehner@apple.com>2014-10-01 00:13:22 +0000
commit08cc4b950cac86d704ff57a89ee8754cb035bd9e (patch)
treeca8b269ea9bbd862462e97098697b23dc4d28722 /llvm/test
parent438903d1b2cda72ad416ecd3da981487f2146aa2 (diff)
downloadbcm5719-llvm-08cc4b950cac86d704ff57a89ee8754cb035bd9e.tar.gz
bcm5719-llvm-08cc4b950cac86d704ff57a89ee8754cb035bd9e.zip
[InstCombine] Optimize icmp-select-icmp
In special cases select instructions can be eliminated by replacing them with a cheaper bitwise operation even when the select result is used outside its home block. The instances implemented are patterns like %x=icmp.eq %y=select %x,%r, null %z=icmp.eq|neq %y, null br %z,true, false ==> %x=icmp.ne %y=icmp.eq %r,null %z=or %x,%y br %z,true,false The optimization is integrated into the instruction combiner and performed only when all uses of the select result can be replaced by the select operand proper. For this dominator information is used and dominance is now a required analysis pass in the combiner. The optimization itself is iterative. The critical step is to replace the select result with the non-constant select operand. So the select becomes local and the combiner iteratively works out simpler code pattern and eventually eliminates the select. rdar://17853760 llvm-svn: 218721
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/Transforms/InstCombine/pr12338.ll2
-rw-r--r--llvm/test/Transforms/InstCombine/select-cmp-br.ll127
2 files changed, 128 insertions, 1 deletions
diff --git a/llvm/test/Transforms/InstCombine/pr12338.ll b/llvm/test/Transforms/InstCombine/pr12338.ll
index d34600f0fa5..051c21ca41a 100644
--- a/llvm/test/Transforms/InstCombine/pr12338.ll
+++ b/llvm/test/Transforms/InstCombine/pr12338.ll
@@ -2,11 +2,11 @@
define void @entry() nounwind {
entry:
+; CHECK: br label %for.cond
br label %for.cond
for.cond:
%local = phi <1 x i32> [ <i32 0>, %entry ], [ %phi2, %cond.end47 ]
-; CHECK: sub <1 x i32> <i32 92>, %local
%phi3 = sub <1 x i32> zeroinitializer, %local
br label %cond.end
diff --git a/llvm/test/Transforms/InstCombine/select-cmp-br.ll b/llvm/test/Transforms/InstCombine/select-cmp-br.ll
new file mode 100644
index 00000000000..2e999510b42
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/select-cmp-br.ll
@@ -0,0 +1,127 @@
+; Replace a 'select' with 'or' in 'select - cmp [eq|ne] - br' sequence
+; RUN: opt -instcombine -S < %s | FileCheck %s
+
+%C = type <{ %struct.S }>
+%struct.S = type { i64*, i32, i32 }
+
+declare void @bar(%struct.S *) #1
+
+define void @test1(%C*) {
+entry:
+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0
+ %m = load i64** %1, align 8
+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0
+ %n = load i64** %2, align 8
+ %3 = getelementptr inbounds i64* %m, i64 9
+ %4 = bitcast i64* %3 to i64 (%C*)**
+ %5 = load i64 (%C*)** %4, align 8
+ %6 = icmp eq i64* %m, %n
+ %7 = select i1 %6, %C* %0, %C* null
+ %8 = icmp eq %C* %7, null
+ br i1 %8, label %12, label %10
+
+; <label>:9 ; preds = %10, %12
+ ret void
+
+; <label>:10 ; preds = %entry
+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0
+ tail call void @bar(%struct.S* %11)
+ br label %9
+
+; <label>:12 ; preds = %entry
+ %13 = tail call i64 %5(%C* %0)
+ br label %9
+; CHECK-LABEL: @test1(
+; CHECK-NOT: select
+; CHECK: or
+}
+
+define void @test2(%C*) {
+entry:
+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0
+ %m = load i64** %1, align 8
+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0
+ %n = load i64** %2, align 8
+ %3 = getelementptr inbounds i64* %m, i64 9
+ %4 = bitcast i64* %3 to i64 (%C*)**
+ %5 = load i64 (%C*)** %4, align 8
+ %6 = icmp eq i64* %m, %n
+ %7 = select i1 %6, %C* null, %C* %0
+ %8 = icmp eq %C* %7, null
+ br i1 %8, label %12, label %10
+
+; <label>:9 ; preds = %10, %12
+ ret void
+
+; <label>:10 ; preds = %entry
+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0
+ tail call void @bar(%struct.S* %11)
+ br label %9
+
+; <label>:12 ; preds = %entry
+ %13 = tail call i64 %5(%C* %0)
+ br label %9
+; CHECK-LABEL: @test2(
+; CHECK-NOT: select
+; CHECK: or
+}
+
+define void @test3(%C*) {
+entry:
+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0
+ %m = load i64** %1, align 8
+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0
+ %n = load i64** %2, align 8
+ %3 = getelementptr inbounds i64* %m, i64 9
+ %4 = bitcast i64* %3 to i64 (%C*)**
+ %5 = load i64 (%C*)** %4, align 8
+ %6 = icmp eq i64* %m, %n
+ %7 = select i1 %6, %C* %0, %C* null
+ %8 = icmp ne %C* %7, null
+ br i1 %8, label %10, label %12
+
+; <label>:9 ; preds = %10, %12
+ ret void
+
+; <label>:10 ; preds = %entry
+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0
+ tail call void @bar(%struct.S* %11)
+ br label %9
+
+; <label>:12 ; preds = %entry
+ %13 = tail call i64 %5(%C* %0)
+ br label %9
+; CHECK-LABEL: @test3(
+; CHECK-NOT: select
+; CHECK: or
+}
+
+define void @test4(%C*) {
+entry:
+ %1 = getelementptr inbounds %C* %0, i64 0, i32 0, i32 0
+ %m = load i64** %1, align 8
+ %2 = getelementptr inbounds %C* %0, i64 1, i32 0, i32 0
+ %n = load i64** %2, align 8
+ %3 = getelementptr inbounds i64* %m, i64 9
+ %4 = bitcast i64* %3 to i64 (%C*)**
+ %5 = load i64 (%C*)** %4, align 8
+ %6 = icmp eq i64* %m, %n
+ %7 = select i1 %6, %C* null, %C* %0
+ %8 = icmp ne %C* %7, null
+ br i1 %8, label %10, label %12
+
+; <label>:9 ; preds = %10, %12
+ ret void
+
+; <label>:10 ; preds = %entry
+ %11 = getelementptr inbounds %C* %7, i64 0, i32 0
+ tail call void @bar(%struct.S* %11)
+ br label %9
+
+; <label>:12 ; preds = %entry
+ %13 = tail call i64 %5(%C* %0)
+ br label %9
+; CHECK-LABEL: @test4(
+; CHECK-NOT: select
+; CHECK: or
+}
OpenPOWER on IntegriCloud