1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes="loop-mssa(indvars,simple-loop-unswitch<nontrivial>)" -verify-scev -S %s | FileCheck %s 3target datalayout = "n16:32" 4 5@glob = external global i16, align 1 6 7; Test case for PR58136. 8define void @test_pr58136(i1 %c.1, i1 %c.2) { 9; CHECK-LABEL: @test_pr58136( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: [[SRC1:%.*]] = alloca i16, align 2 12; CHECK-NEXT: [[L_3:%.*]] = load i16, ptr [[SRC1]], align 2 13; CHECK-NEXT: [[GLOB_PROMOTED:%.*]] = load i16, ptr @glob, align 2 14; CHECK-NEXT: [[C_1_FR:%.*]] = freeze i1 [[C_1:%.*]] 15; CHECK-NEXT: br i1 [[C_1_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 16; CHECK: entry.split.us: 17; CHECK-NEXT: [[C_2_FR:%.*]] = freeze i1 [[C_2:%.*]] 18; CHECK-NEXT: br i1 [[C_2_FR]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]], label [[ENTRY_SPLIT_US_SPLIT:%.*]] 19; CHECK: entry.split.us.split.us: 20; CHECK-NEXT: br label [[LOOP_HEADER_US_US:%.*]] 21; CHECK: loop.header.us.us: 22; CHECK-NEXT: [[MUL1_US_US:%.*]] = phi i16 [ [[MUL_US_US:%.*]], [[LOOP_LATCH_US_US:%.*]] ], [ [[GLOB_PROMOTED]], [[ENTRY_SPLIT_US_SPLIT_US]] ] 23; CHECK-NEXT: [[CALL2_US_US:%.*]] = call i16 @foo() 24; CHECK-NEXT: br label [[THEN_BB_US_US:%.*]] 25; CHECK: then.bb.us.us: 26; CHECK-NEXT: br label [[LOOP_LATCH_US_US]] 27; CHECK: loop.latch.us.us: 28; CHECK-NEXT: [[MUL_US_US]] = mul nsw i16 [[MUL1_US_US]], [[L_3]] 29; CHECK-NEXT: store i16 [[MUL_US_US]], ptr @glob, align 2 30; CHECK-NEXT: br label [[LOOP_HEADER_US_US]] 31; CHECK: entry.split.us.split: 32; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] 33; CHECK: loop.header.us: 34; CHECK-NEXT: [[CALL2_US:%.*]] = call i16 @foo() 35; CHECK-NEXT: br label [[THEN_BB_US:%.*]] 36; CHECK: then.bb.us: 37; CHECK-NEXT: br label [[EXIT_SPLIT_US:%.*]] 38; CHECK: exit.split.us: 39; CHECK-NEXT: br label [[EXIT:%.*]] 40; CHECK: entry.split: 41; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 42; CHECK: loop.header: 43; CHECK-NEXT: [[CALL2:%.*]] = call i16 @foo() 44; CHECK-NEXT: br label [[EXIT_SPLIT:%.*]] 45; CHECK: exit.split: 46; CHECK-NEXT: br label [[EXIT]] 47; CHECK: exit: 48; CHECK-NEXT: ret void 49; 50entry: 51 %src1 = alloca i16, align 2 52 %l.3 = load i16, ptr %src1, align 2 53 %glob.promoted = load i16, ptr @glob, align 2 54 br label %loop.header 55 56loop.header: ; preds = %loop.latch, %entry 57 %mul1 = phi i16 [ %mul, %loop.latch ], [ %glob.promoted, %entry ] 58 %call2 = call i16 @foo() 59 br i1 %c.1, label %then.bb, label %exit 60 61then.bb: ; preds = %loop.header 62 br i1 %c.2, label %loop.latch, label %exit 63 64loop.latch: ; preds = %then.bb 65 %mul = mul nsw i16 %mul1, %l.3 66 store i16 %mul, ptr @glob, align 2 67 br label %loop.header 68 69exit: ; preds = %then.bb, %loop.header 70 ret void 71} 72 73declare i16 @foo() nounwind readnone 74 75define void @test_pr58158(i1 %c.1) { 76; CHECK-LABEL: @test_pr58158( 77; CHECK-NEXT: entry: 78; CHECK-NEXT: [[CALL:%.*]] = tail call i16 @bar() 79; CHECK-NEXT: br i1 [[C_1:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 80; CHECK: entry.split.us: 81; CHECK-NEXT: br label [[OUTER_US:%.*]] 82; CHECK: outer.us: 83; CHECK-NEXT: br label [[INNER_PREHEADER_US:%.*]] 84; CHECK: inner.us: 85; CHECK-NEXT: [[C_2_US:%.*]] = icmp eq i16 0, [[CALL]] 86; CHECK-NEXT: br i1 [[C_2_US]], label [[OUTER_LOOPEXIT_US:%.*]], label [[INNER_US:%.*]] 87; CHECK: inner.preheader.us: 88; CHECK-NEXT: br label [[INNER_US]] 89; CHECK: outer.loopexit.us: 90; CHECK-NEXT: br label [[OUTER_BACKEDGE_US:%.*]] 91; CHECK: outer.backedge.us: 92; CHECK-NEXT: br label [[OUTER_US]] 93; CHECK: entry.split: 94; CHECK-NEXT: br label [[OUTER:%.*]] 95; CHECK: outer: 96; CHECK-NEXT: br label [[OUTER_BACKEDGE:%.*]] 97; CHECK: outer.backedge: 98; CHECK-NEXT: br label [[OUTER]] 99; 100entry: 101 %call = tail call i16 @bar() 102 br label %outer 103 104outer: 105 br i1 %c.1, label %inner, label %outer 106 107inner: 108 %c.2 = icmp eq i16 0, %call 109 br i1 %c.2, label %outer, label %inner 110} 111 112declare i16 @bar() 113 114define void @pr58751(i16 %a, ptr %dst) { 115entry: 116 %c.1 = icmp eq i16 %a, 0 117 br label %outer.header 118 119outer.header: 120 %outer.iv = phi i16 [ %a, %entry ], [ %outer.iv.next, %outer.latch ] 121 br label %inner.header 122 123inner.header: 124 %inner.iv = phi i16 [ %outer.iv, %outer.header ], [ %inner.iv.next, %inner.latch ] 125 br i1 %c.1, label %outer.latch, label %inner.latch 126 127inner.latch: 128 %inner.iv.next = add nsw i16 %inner.iv, 1 129 store i16 %inner.iv.next, ptr %dst, align 1 130 %c.2 = icmp eq i16 %inner.iv.next, 0 131 br i1 %c.2, label %exit, label %inner.header 132 133outer.latch: 134 %outer.iv.next = add nsw i16 %outer.iv, 1 135 br label %outer.header 136 137exit: 138 ret void 139} 140 141