; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -passes='simple-loop-unswitch<nontrivial>' -S < %s | FileCheck %s ; If we try to replace uses of `true` outside of `@foo`, we'll see it here. define i1 @bar() { ; CHECK-LABEL: @bar( ; CHECK-NEXT: ret i1 true ; ret i1 true } ; We shouldn't unswitch this loop. define void @foo() { ; CHECK-LABEL: @foo( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[HEADER:%.*]] ; CHECK: header: ; CHECK-NEXT: [[VAL:%.*]] = select i1 true, i1 true, i1 false ; CHECK-NEXT: br i1 [[VAL]], label [[EXIT:%.*]], label [[HEADER]] ; CHECK: exit: ; CHECK-NEXT: ret void ; entry: br label %header header: %val = select i1 true, i1 true, i1 false br i1 %val, label %exit, label %header exit: ret void } define void @unswitch_trivial_select(i1 %c.1, i1 %c.2, i8 %a) { ; CHECK-LABEL: @unswitch_trivial_select( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[PH_1:%.*]], label [[EXIT:%.*]] ; CHECK: ph.1: ; CHECK-NEXT: br i1 [[C_2:%.*]], label [[PH_2:%.*]], label [[EXIT]] ; CHECK: ph.2: ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 30 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i1 true, i1 false ; CHECK-NEXT: [[CMP_FR:%.*]] = freeze i1 [[CMP]] ; CHECK-NEXT: br i1 [[CMP_FR]], label [[PH_2_SPLIT_US:%.*]], label [[PH_2_SPLIT:%.*]] ; CHECK: ph.2.split.us: ; CHECK-NEXT: br label [[LOOP_US:%.*]] ; CHECK: loop.us: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[EXIT_LOOPEXIT_SPLIT_US:%.*]] ; CHECK: exit.loopexit.split.us: ; CHECK-NEXT: br label [[EXIT_LOOPEXIT:%.*]] ; CHECK: ph.2.split: ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: call void @foo() ; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] ; CHECK: loop.latch: ; CHECK-NEXT: br label [[LOOP]] ; CHECK: exit.loopexit: ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void ; entry: br i1 %c.1, label %ph.1, label %exit ph.1: br i1 %c.2, label %ph.2, label %exit ph.2: %cmp = icmp eq i8 %a, 30 %sel = select i1 %cmp, i1 true, i1 false br label %loop loop: call void @foo() br i1 %sel, label %exit, label %loop.latch loop.latch: br label %loop exit: ret void } ; Test case for PR55697. define i32 @unswitch_trivial_select_cmp_outside(i32 %x) { ; CHECK-LABEL: @unswitch_trivial_select_cmp_outside( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], 100 ; CHECK-NEXT: br i1 [[C]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] ; CHECK: entry.split.us: ; CHECK-NEXT: br label [[LOOP_US:%.*]] ; CHECK: loop.us: ; CHECK-NEXT: [[P_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ 35, [[LOOP_US]] ] ; CHECK-NEXT: br label [[LOOP_US]] ; CHECK: entry.split: ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ] ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 false, i1 true, i1 false ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: [[LCSSA:%.*]] = phi i32 [ [[P]], [[LOOP]] ] ; CHECK-NEXT: ret i32 [[LCSSA]] ; entry: %c = icmp ult i32 %x, 100 br label %loop loop: %p = phi i32 [ 0, %entry ], [ 35, %loop ] %spec.select = select i1 %c, i1 true, i1 false br i1 %spec.select, label %loop, label %exit exit: %lcssa = phi i32 [ %p, %loop ] ret i32 %lcssa }