| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -S -p iroutliner,verify -ir-outlining-no-cost < %s | FileCheck %s |
| |
| ; This test checks that commutative instructions where the operands are |
| ; swapped are outlined as the same function. |
| |
| ; It also checks that non-commutative instructions outlined as different |
| ; functions when the operands are swapped; |
| |
| ; These are identical functions, except that in the flipped functions, |
| ; the operands in the adds are commuted. However, since add instructions |
| ; are commutative, we should still outline from all four as the same |
| ; instruction. |
| |
| define void @function1(i32 %a, i32 %b) { |
| ; CHECK-LABEL: @function1( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br label [[BLOCK_1:%.*]] |
| ; CHECK: block_0: |
| ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[A:%.*]], [[B:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP4:%.*]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP0]], [[TMP0]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP0]] |
| ; CHECK-NEXT: br i1 [[TMP3]], label [[BLOCK_1]], label [[BLOCK_2:%.*]] |
| ; CHECK: block_1: |
| ; CHECK-NEXT: [[TMP4]] = phi i32 [ [[TMP1]], [[BLOCK_0:%.*]] ], [ 0, [[ENTRY:%.*]] ] |
| ; CHECK-NEXT: call void @outlined_ir_func_0(i32 [[B]]) |
| ; CHECK-NEXT: br label [[BLOCK_0]] |
| ; CHECK: block_2: |
| ; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[TMP2]], [[TMP2]] |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| br label %block_1 |
| |
| block_0: |
| %0 = add i32 %a, %b |
| %1 = add i32 %4, 1 |
| %2 = add i32 %0, %0 |
| %3 = icmp sgt i32 %0, %0 |
| br i1 %3, label %block_1, label %block_2 |
| |
| block_1: |
| %4 = phi i32 [ %1, %block_0 ], [ 0, %entry ] |
| %5 = add i32 %b, %b |
| br label %block_0 |
| |
| block_2: |
| %6 = add i32 %2, %2 |
| ret void |
| } |
| |
| define void @function2(i32 %a, i32 %b) { |
| ; CHECK-LABEL: @function2( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br label [[BLOCK_1:%.*]] |
| ; CHECK: block_0: |
| ; CHECK-NEXT: [[TMP0:%.*]] = sub i32 [[A:%.*]], [[B:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 1, [[TMP4:%.*]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP0]], [[TMP0]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP0]] |
| ; CHECK-NEXT: br i1 [[TMP3]], label [[BLOCK_1]], label [[BLOCK_2:%.*]] |
| ; CHECK: block_1: |
| ; CHECK-NEXT: [[TMP4]] = phi i32 [ [[TMP1]], [[BLOCK_0:%.*]] ], [ 0, [[ENTRY:%.*]] ] |
| ; CHECK-NEXT: call void @outlined_ir_func_0(i32 [[B]]) |
| ; CHECK-NEXT: br label [[BLOCK_0]] |
| ; CHECK: block_2: |
| ; CHECK-NEXT: [[TMP5:%.*]] = sub i32 [[TMP2]], [[TMP2]] |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| br label %block_1 |
| |
| block_0: |
| %0 = sub i32 %a, %b |
| %1 = add i32 1, %4 |
| %2 = add i32 %0, %0 |
| %3 = icmp sgt i32 %0, %0 |
| br i1 %3, label %block_1, label %block_2 |
| |
| block_1: |
| %4 = phi i32 [ %1, %block_0 ], [ 0, %entry ] |
| %5 = add i32 %b, %b |
| br label %block_0 |
| |
| block_2: |
| %6 = sub i32 %2, %2 |
| ret void |
| } |