| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
| ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s | |
| ; PR12189 | |
| define i1 @test1(i32 %x) { | |
| ; CHECK-LABEL: @test1( | |
| ; CHECK-NEXT: br i1 true, label [[A:%.*]], label [[B:%.*]] | |
| ; CHECK: a: | |
| ; CHECK-NEXT: [[AA:%.*]] = or i32 [[X:%.*]], 10 | |
| ; CHECK-NEXT: br label [[C:%.*]] | |
| ; CHECK: b: | |
| ; CHECK-NEXT: [[BB:%.*]] = or i32 [[X]], 10 | |
| ; CHECK-NEXT: br label [[C]] | |
| ; CHECK: c: | |
| ; CHECK-NEXT: [[CC:%.*]] = phi i32 [ [[BB]], [[B]] ], [ [[AA]], [[A]] ] | |
| ; CHECK-NEXT: [[D:%.*]] = urem i32 [[CC]], 2 | |
| ; CHECK-NEXT: [[E:%.*]] = icmp eq i32 [[D]], 0 | |
| ; CHECK-NEXT: ret i1 [[E]] | |
| ; | |
| br i1 true, label %a, label %b | |
| a: | |
| %aa = or i32 %x, 10 | |
| br label %c | |
| b: | |
| %bb = or i32 %x, 10 | |
| br label %c | |
| c: | |
| %cc = phi i32 [ %bb, %b ], [%aa, %a ] | |
| %d = urem i32 %cc, 2 | |
| %e = icmp eq i32 %d, 0 | |
| ret i1 %e | |
| } | |
| ; D63489 - https://reviews.llvm.org/D63489 | |
| ; If this single-value phi form needs to be preserved to enable | |
| ; further analysis, then -passes=instsimplify should not be running? | |
| define i32 @lcssa-phi(i32 %x) { | |
| ; CHECK-LABEL: @lcssa-phi( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[END:%.*]] | |
| ; CHECK: end: | |
| ; CHECK-NEXT: ret i32 [[X:%.*]] | |
| ; | |
| entry: | |
| br label %end | |
| end: | |
| %counter.lcssa = phi i32 [ %x, %entry ] | |
| ret i32 %counter.lcssa | |
| } | |
| define i32 @poison(i1 %cond, i32 %v) { | |
| ; CHECK-LABEL: @poison( | |
| ; CHECK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]] | |
| ; CHECK: A: | |
| ; CHECK-NEXT: br label [[EXIT:%.*]] | |
| ; CHECK: B: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: EXIT: | |
| ; CHECK-NEXT: ret i32 [[V:%.*]] | |
| ; | |
| br i1 %cond, label %A, label %B | |
| A: | |
| br label %EXIT | |
| B: | |
| br label %EXIT | |
| EXIT: | |
| %w = phi i32 [%v, %A], [poison, %B] | |
| ret i32 %w | |
| } | |
| define i32 @undef(i1 %cond, i32 %v) { | |
| ; CHECK-LABEL: @undef( | |
| ; CHECK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]] | |
| ; CHECK: A: | |
| ; CHECK-NEXT: br label [[EXIT:%.*]] | |
| ; CHECK: B: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: EXIT: | |
| ; CHECK-NEXT: [[W:%.*]] = phi i32 [ [[V:%.*]], [[A]] ], [ undef, [[B]] ] | |
| ; CHECK-NEXT: ret i32 [[W]] | |
| ; | |
| br i1 %cond, label %A, label %B | |
| A: | |
| br label %EXIT | |
| B: | |
| br label %EXIT | |
| EXIT: | |
| %w = phi i32 [%v, %A], [undef, %B] | |
| ret i32 %w | |
| } | |
| define i8 @undef_poison(i1 %cond) { | |
| ; CHECK-LABEL: @undef_poison( | |
| ; CHECK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]] | |
| ; CHECK: A: | |
| ; CHECK-NEXT: br label [[EXIT:%.*]] | |
| ; CHECK: B: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: EXIT: | |
| ; CHECK-NEXT: ret i8 undef | |
| ; | |
| br i1 %cond, label %A, label %B | |
| A: | |
| br label %EXIT | |
| B: | |
| br label %EXIT | |
| EXIT: | |
| %r = phi i8 [undef, %A], [poison, %B] | |
| ret i8 %r | |
| } | |
| define i8 @only_undef(i1 %cond) { | |
| ; CHECK-LABEL: @only_undef( | |
| ; CHECK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]] | |
| ; CHECK: A: | |
| ; CHECK-NEXT: br label [[EXIT:%.*]] | |
| ; CHECK: B: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: EXIT: | |
| ; CHECK-NEXT: ret i8 undef | |
| ; | |
| br i1 %cond, label %A, label %B | |
| A: | |
| br label %EXIT | |
| B: | |
| br label %EXIT | |
| EXIT: | |
| %r = phi i8 [undef, %A], [undef, %B] | |
| ret i8 %r | |
| } | |
| define i8 @only_poison(i1 %cond) { | |
| ; CHECK-LABEL: @only_poison( | |
| ; CHECK-NEXT: br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]] | |
| ; CHECK: A: | |
| ; CHECK-NEXT: br label [[EXIT:%.*]] | |
| ; CHECK: B: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: EXIT: | |
| ; CHECK-NEXT: ret i8 poison | |
| ; | |
| br i1 %cond, label %A, label %B | |
| A: | |
| br label %EXIT | |
| B: | |
| br label %EXIT | |
| EXIT: | |
| %r = phi i8 [poison, %A], [poison, %B] | |
| ret i8 %r | |
| } | |
| ; Should not fold srem to -1 due to incorrect context instruction when | |
| ; threading over phi. | |
| define i32 @pr61312() { | |
| ; CHECK-LABEL: @pr61312( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[FOR_COND:%.*]] | |
| ; CHECK: for.cond: | |
| ; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[DEC:%.*]], [[FOR_INC:%.*]] ] | |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A_0]], 0 | |
| ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_INC]], label [[FOR_END:%.*]] | |
| ; CHECK: for.inc: | |
| ; CHECK-NEXT: [[DEC]] = add nsw i32 [[A_0]], -1 | |
| ; CHECK-NEXT: br label [[FOR_COND]] | |
| ; CHECK: for.end: | |
| ; CHECK-NEXT: [[REM:%.*]] = srem i32 -1, [[A_0]] | |
| ; CHECK-NEXT: ret i32 [[REM]] | |
| ; | |
| entry: | |
| br label %for.cond | |
| for.cond: | |
| %a.0 = phi i32 [ 2, %entry ], [ %dec, %for.inc ] | |
| %cmp = icmp sge i32 %a.0, 0 | |
| br i1 %cmp, label %for.inc, label %for.end | |
| for.inc: | |
| %dec = add nsw i32 %a.0, -1 | |
| br label %for.cond | |
| for.end: | |
| %rem = srem i32 -1, %a.0 | |
| ret i32 %rem | |
| } |