diff options
Diffstat (limited to 'llvm/test/Transforms')
| -rw-r--r-- | llvm/test/Transforms/EarlyCSE/conditional.ll | 107 | ||||
| -rw-r--r-- | llvm/test/Transforms/EarlyCSE/edge.ll | 174 |
2 files changed, 281 insertions, 0 deletions
diff --git a/llvm/test/Transforms/EarlyCSE/conditional.ll b/llvm/test/Transforms/EarlyCSE/conditional.ll new file mode 100644 index 00000000000..5b5a74f112b --- /dev/null +++ b/llvm/test/Transforms/EarlyCSE/conditional.ll @@ -0,0 +1,107 @@ +; RUN: opt -early-cse -S < %s | FileCheck %s + +; Can we CSE a known condition to a constant? +define i1 @test(i8* %p) { +; CHECK-LABEL: @test +entry: + %cnd1 = icmp eq i8* %p, null + br i1 %cnd1, label %taken, label %untaken + +taken: +; CHECK-LABEL: taken: +; CHECK-NEXT: ret i1 true + %cnd2 = icmp eq i8* %p, null + ret i1 %cnd2 + +untaken: +; CHECK-LABEL: untaken: +; CHECK-NEXT: ret i1 false + %cnd3 = icmp eq i8* %p, null + ret i1 %cnd3 +} + +; We can CSE the condition, but we *don't* know it's value after the merge +define i1 @test_neg1(i8* %p) { +; CHECK-LABEL: @test_neg1 +entry: + %cnd1 = icmp eq i8* %p, null + br i1 %cnd1, label %taken, label %untaken + +taken: + br label %merge + +untaken: + br label %merge + +merge: +; CHECK-LABEL: merge: +; CHECK-NEXT: ret i1 %cnd1 + %cnd3 = icmp eq i8* %p, null + ret i1 %cnd3 +} + +; Check specifically for a case where we have a unique predecessor, but +; not a single predecessor. We can not know the value of the condition here. +define i1 @test_neg2(i8* %p) { +; CHECK-LABEL: @test_neg2 +entry: + %cnd1 = icmp eq i8* %p, null + br i1 %cnd1, label %merge, label %merge + +merge: +; CHECK-LABEL: merge: +; CHECK-NEXT: ret i1 %cnd1 + %cnd3 = icmp eq i8* %p, null + ret i1 %cnd3 +} + +; Replace a use rather than CSE +define i1 @test2(i8* %p) { +; CHECK-LABEL: @test2 +entry: + %cnd = icmp eq i8* %p, null + br i1 %cnd, label %taken, label %untaken + +taken: +; CHECK-LABEL: taken: +; CHECK-NEXT: ret i1 true + ret i1 %cnd + +untaken: +; CHECK-LABEL: untaken: +; CHECK-NEXT: ret i1 false + ret i1 %cnd +} + +; Not legal to replace use given it's not dominated by edge +define i1 @test2_neg1(i8* %p) { +; CHECK-LABEL: @test2_neg1 +entry: + %cnd1 = icmp eq i8* %p, null + br i1 %cnd1, label %taken, label %untaken + +taken: + br label %merge + +untaken: + br label %merge + +merge: +; CHECK-LABEL: merge: +; CHECK-NEXT: ret i1 %cnd1 + ret i1 %cnd1 +} + +; Another single predecessor test, but for dominated use +define i1 @test2_neg2(i8* %p) { +; CHECK-LABEL: @test2_neg2 +entry: + %cnd1 = icmp eq i8* %p, null + br i1 %cnd1, label %merge, label %merge + +merge: +; CHECK-LABEL: merge: +; CHECK-NEXT: ret i1 %cnd1 + ret i1 %cnd1 +} + diff --git a/llvm/test/Transforms/EarlyCSE/edge.ll b/llvm/test/Transforms/EarlyCSE/edge.ll new file mode 100644 index 00000000000..94b29260375 --- /dev/null +++ b/llvm/test/Transforms/EarlyCSE/edge.ll @@ -0,0 +1,174 @@ +; RUN: opt -early-cse -S < %s | FileCheck %s +; Same as GVN/edge.ll, but updated to reflect EarlyCSE's less powerful +; implementation. EarlyCSE doesn't yet handle uses on edges where the +; source is dominated, but the dest is not. Nor does it reason about +; fcmps. This file can basically be seen as a list of TODOs. + +define i32 @f1(i32 %x) { + ; CHECK-LABEL: define i32 @f1( +bb0: + %cmp = icmp eq i32 %x, 0 + br i1 %cmp, label %bb2, label %bb1 +bb1: + br label %bb2 +bb2: + %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ] + %foo = add i32 %cond, %x + ret i32 %foo + ; CHECK: bb2: + ; CHECK: %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ] +} + +define i32 @f2(i32 %x) { + ; CHECK-LABEL: define i32 @f2( +bb0: + %cmp = icmp ne i32 %x, 0 + br i1 %cmp, label %bb1, label %bb2 +bb1: + br label %bb2 +bb2: + %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ] + %foo = add i32 %cond, %x + ret i32 %foo + ; CHECK: bb2: + ; CHECK: %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ] +} + +define i32 @f3(i32 %x) { + ; CHECK-LABEL: define i32 @f3( +bb0: + switch i32 %x, label %bb1 [ i32 0, label %bb2] +bb1: + br label %bb2 +bb2: + %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ] + %foo = add i32 %cond, %x + ret i32 %foo + ; CHECK: bb2: + ; CHECK: %cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ] +} + +declare void @g(i1) +define void @f4(i8 * %x) { +; CHECK-LABEL: define void @f4( +bb0: + %y = icmp eq i8* null, %x + br i1 %y, label %bb2, label %bb1 +bb1: + br label %bb2 +bb2: + %zed = icmp eq i8* null, %x + call void @g(i1 %zed) +; CHECK: call void @g(i1 %y) + ret void +} + +define double @fcmp_oeq_not_zero(double %x, double %y) { +entry: + %cmp = fcmp oeq double %y, 2.0 + br i1 %cmp, label %if, label %return + +if: + %div = fdiv double %x, %y + br label %return + +return: + %retval = phi double [ %div, %if ], [ %x, %entry ] + ret double %retval + +; CHECK-LABEL: define double @fcmp_oeq_not_zero( +; CHECK: %div = fdiv double %x, %y +} + +define double @fcmp_une_not_zero(double %x, double %y) { +entry: + %cmp = fcmp une double %y, 2.0 + br i1 %cmp, label %return, label %else + +else: + %div = fdiv double %x, %y + br label %return + +return: + %retval = phi double [ %div, %else ], [ %x, %entry ] + ret double %retval + +; CHECK-LABEL: define double @fcmp_une_not_zero( +; CHECK: %div = fdiv double %x, %y +} + +; PR22376 - We can't propagate zero constants because -0.0 +; compares equal to 0.0. If %y is -0.0 in this test case, +; we would produce the wrong sign on the infinity return value. +define double @fcmp_oeq_zero(double %x, double %y) { +entry: + %cmp = fcmp oeq double %y, 0.0 + br i1 %cmp, label %if, label %return + +if: + %div = fdiv double %x, %y + br label %return + +return: + %retval = phi double [ %div, %if ], [ %x, %entry ] + ret double %retval + +; CHECK-LABEL: define double @fcmp_oeq_zero( +; CHECK: %div = fdiv double %x, %y +} + +define double @fcmp_une_zero(double %x, double %y) { +entry: + %cmp = fcmp une double %y, -0.0 + br i1 %cmp, label %return, label %else + +else: + %div = fdiv double %x, %y + br label %return + +return: + %retval = phi double [ %div, %else ], [ %x, %entry ] + ret double %retval + +; CHECK-LABEL: define double @fcmp_une_zero( +; CHECK: %div = fdiv double %x, %y +} + +; We also cannot propagate a value if it's not a constant. +; This is because the value could be 0.0 or -0.0. + +define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) { +entry: + %z = fadd double %z1, %z2 + %cmp = fcmp oeq double %y, %z + br i1 %cmp, label %if, label %return + +if: + %div = fdiv double %x, %z + br label %return + +return: + %retval = phi double [ %div, %if ], [ %x, %entry ] + ret double %retval + +; CHECK-LABEL: define double @fcmp_oeq_maybe_zero( +; CHECK: %div = fdiv double %x, %z +} + +define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) { +entry: + %z = fadd double %z1, %z2 + %cmp = fcmp une double %y, %z + br i1 %cmp, label %return, label %else + +else: + %div = fdiv double %x, %z + br label %return + +return: + %retval = phi double [ %div, %else ], [ %x, %entry ] + ret double %retval + +; CHECK-LABEL: define double @fcmp_une_maybe_zero( +; CHECK: %div = fdiv double %x, %z +} |

