| ; RUN: opt -passes=early-cse -earlycse-debug-hash -S < %s | FileCheck %s |
| ; RUN: opt -passes='early-cse<memssa>' -S < %s | FileCheck %s |
| |
| ; Can we CSE a known condition to a constant? |
| define i1 @test(ptr %p) { |
| ; CHECK-LABEL: @test |
| entry: |
| %cnd1 = icmp eq ptr %p, null |
| br i1 %cnd1, label %taken, label %untaken |
| |
| taken: |
| ; CHECK-LABEL: taken: |
| ; CHECK-NEXT: ret i1 true |
| %cnd2 = icmp eq ptr %p, null |
| ret i1 %cnd2 |
| |
| untaken: |
| ; CHECK-LABEL: untaken: |
| ; CHECK-NEXT: ret i1 false |
| %cnd3 = icmp eq ptr %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(ptr %p) { |
| ; CHECK-LABEL: @test_neg1 |
| entry: |
| %cnd1 = icmp eq ptr %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 ptr %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(ptr %p) { |
| ; CHECK-LABEL: @test_neg2 |
| entry: |
| %cnd1 = icmp eq ptr %p, null |
| br i1 %cnd1, label %merge, label %merge |
| |
| merge: |
| ; CHECK-LABEL: merge: |
| ; CHECK-NEXT: ret i1 %cnd1 |
| %cnd3 = icmp eq ptr %p, null |
| ret i1 %cnd3 |
| } |
| |
| ; Replace a use rather than CSE |
| define i1 @test2(ptr %p) { |
| ; CHECK-LABEL: @test2 |
| entry: |
| %cnd = icmp eq ptr %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(ptr %p) { |
| ; CHECK-LABEL: @test2_neg1 |
| entry: |
| %cnd1 = icmp eq ptr %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(ptr %p) { |
| ; CHECK-LABEL: @test2_neg2 |
| entry: |
| %cnd1 = icmp eq ptr %p, null |
| br i1 %cnd1, label %merge, label %merge |
| |
| merge: |
| ; CHECK-LABEL: merge: |
| ; CHECK-NEXT: ret i1 %cnd1 |
| ret i1 %cnd1 |
| } |
| |