diff options
author | Gerolf Hoflehner <ghoflehner@apple.com> | 2014-10-01 00:13:22 +0000 |
---|---|---|
committer | Gerolf Hoflehner <ghoflehner@apple.com> | 2014-10-01 00:13:22 +0000 |
commit | 08cc4b950cac86d704ff57a89ee8754cb035bd9e (patch) | |
tree | ca8b269ea9bbd862462e97098697b23dc4d28722 /llvm/test | |
parent | 438903d1b2cda72ad416ecd3da981487f2146aa2 (diff) | |
download | bcm5719-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.ll | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/select-cmp-br.ll | 127 |
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 +} |