; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S --passes='simplifycfg' -simplifycfg-hoist-common-skip-limit=0 %s | FileCheck %s --check-prefix=LIMIT0 ; RUN: opt -S --passes='simplifycfg' -simplifycfg-hoist-common-skip-limit=1 %s | FileCheck %s --check-prefix=LIMIT1 ; RUN: opt -S --passes='simplifycfg' -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