| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -S --passes='simplifycfg<hoist-common-insts>' -simplifycfg-hoist-common-skip-limit=0 %s | FileCheck %s --check-prefix=LIMIT0 |
| ; RUN: opt -S --passes='simplifycfg<hoist-common-insts>' -simplifycfg-hoist-common-skip-limit=1 %s | FileCheck %s --check-prefix=LIMIT1 |
| ; RUN: opt -S --passes='simplifycfg<hoist-common-insts>' -simplifycfg-hoist-common-skip-limit=2 %s | FileCheck %s --check-prefix=LIMIT2 |
| |
| define void @f(i1 %c, ptr nocapture noundef %d, ptr nocapture noundef readonly %m, ptr nocapture noundef readonly %b) { |
| ; LIMIT0-LABEL: @f( |
| ; LIMIT0-NEXT: entry: |
| ; LIMIT0-NEXT: [[TMP0:%.*]] = load i16, ptr [[B:%.*]], align 2 |
| ; LIMIT0-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] |
| ; LIMIT0: if.then: |
| ; LIMIT0-NEXT: call void @no_side_effects0() |
| ; LIMIT0-NEXT: [[ADD:%.*]] = add nsw i16 [[TMP0]], 1 |
| ; LIMIT0-NEXT: [[TMP1:%.*]] = load i16, ptr [[M:%.*]], align 2 |
| ; LIMIT0-NEXT: [[U:%.*]] = add i16 [[ADD]], [[TMP1]] |
| ; LIMIT0-NEXT: br label [[IF_END:%.*]] |
| ; LIMIT0: if.else: |
| ; LIMIT0-NEXT: call void @no_side_effects1() |
| ; LIMIT0-NEXT: [[SUB:%.*]] = sub nsw i16 [[TMP0]], 1 |
| ; LIMIT0-NEXT: [[TMP2:%.*]] = load i16, ptr [[M]], align 2 |
| ; LIMIT0-NEXT: [[V:%.*]] = add i16 [[SUB]], [[TMP2]] |
| ; LIMIT0-NEXT: br label [[IF_END]] |
| ; LIMIT0: if.end: |
| ; LIMIT0-NEXT: [[UV:%.*]] = phi i16 [ [[V]], [[IF_ELSE]] ], [ [[U]], [[IF_THEN]] ] |
| ; LIMIT0-NEXT: store i16 [[UV]], ptr [[D:%.*]], align 2 |
| ; LIMIT0-NEXT: ret void |
| ; |
| ; LIMIT1-LABEL: @f( |
| ; LIMIT1-NEXT: entry: |
| ; LIMIT1-NEXT: [[TMP0:%.*]] = load i16, ptr [[B:%.*]], align 2 |
| ; LIMIT1-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] |
| ; LIMIT1: if.then: |
| ; LIMIT1-NEXT: call void @no_side_effects0() |
| ; LIMIT1-NEXT: [[ADD:%.*]] = add nsw i16 [[TMP0]], 1 |
| ; LIMIT1-NEXT: [[TMP1:%.*]] = load i16, ptr [[M:%.*]], align 2 |
| ; LIMIT1-NEXT: [[U:%.*]] = add i16 [[ADD]], [[TMP1]] |
| ; LIMIT1-NEXT: br label [[IF_END:%.*]] |
| ; LIMIT1: if.else: |
| ; LIMIT1-NEXT: call void @no_side_effects1() |
| ; LIMIT1-NEXT: [[SUB:%.*]] = sub nsw i16 [[TMP0]], 1 |
| ; LIMIT1-NEXT: [[TMP2:%.*]] = load i16, ptr [[M]], align 2 |
| ; LIMIT1-NEXT: [[V:%.*]] = add i16 [[SUB]], [[TMP2]] |
| ; LIMIT1-NEXT: br label [[IF_END]] |
| ; LIMIT1: if.end: |
| ; LIMIT1-NEXT: [[UV:%.*]] = phi i16 [ [[V]], [[IF_ELSE]] ], [ [[U]], [[IF_THEN]] ] |
| ; LIMIT1-NEXT: store i16 [[UV]], ptr [[D:%.*]], align 2 |
| ; LIMIT1-NEXT: ret void |
| ; |
| ; LIMIT2-LABEL: @f( |
| ; LIMIT2-NEXT: entry: |
| ; LIMIT2-NEXT: [[TMP0:%.*]] = load i16, ptr [[B:%.*]], align 2 |
| ; LIMIT2-NEXT: [[TMP1:%.*]] = load i16, ptr [[M:%.*]], align 2 |
| ; LIMIT2-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] |
| ; LIMIT2: if.then: |
| ; LIMIT2-NEXT: call void @no_side_effects0() |
| ; LIMIT2-NEXT: [[ADD:%.*]] = add nsw i16 [[TMP0]], 1 |
| ; LIMIT2-NEXT: [[U:%.*]] = add i16 [[ADD]], [[TMP1]] |
| ; LIMIT2-NEXT: br label [[IF_END:%.*]] |
| ; LIMIT2: if.else: |
| ; LIMIT2-NEXT: call void @no_side_effects1() |
| ; LIMIT2-NEXT: [[SUB:%.*]] = sub nsw i16 [[TMP0]], 1 |
| ; LIMIT2-NEXT: [[V:%.*]] = add i16 [[SUB]], [[TMP1]] |
| ; LIMIT2-NEXT: br label [[IF_END]] |
| ; LIMIT2: if.end: |
| ; LIMIT2-NEXT: [[UV:%.*]] = phi i16 [ [[V]], [[IF_ELSE]] ], [ [[U]], [[IF_THEN]] ] |
| ; LIMIT2-NEXT: store i16 [[UV]], ptr [[D:%.*]], align 2 |
| ; LIMIT2-NEXT: ret void |
| ; |
| entry: |
| br i1 %c, label %if.then, label %if.else |
| |
| if.then: |
| %0 = load i16, ptr %b, align 2 |
| call void @no_side_effects0() |
| %add = add nsw i16 %0, 1 |
| %1 = load i16, ptr %m, align 2 |
| %u = add i16 %add, %1 |
| br label %if.end |
| |
| if.else: |
| %2 = load i16, ptr %b, align 2 |
| call void @no_side_effects1() |
| %sub = sub nsw i16 %2, 1 |
| %3 = load i16, ptr %m, align 2 |
| %v = add i16 %sub, %3 |
| br label %if.end |
| |
| if.end: |
| %uv = phi i16 [ %v, %if.else ], [ %u, %if.then ] |
| store i16 %uv, ptr %d, align 2 |
| ret void |
| } |
| |
| declare void @side_effects0() |
| declare void @side_effects1() |
| declare void @no_side_effects0() readonly nounwind willreturn |
| declare void @no_side_effects1() readonly nounwind willreturn |