brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.3 KiB · 419ae95 Raw
645 lines · plain
1; RUN: opt < %s -S -passes='loop(loop-flatten),verify' -verify-loop-info -verify-dom-info -verify-scev | FileCheck %s2 3target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"4 5; CHECK-LABEL: test16; Simple loop where the IV's is constant7define i32 @test1(i32 %val, ptr nocapture %A) {8entry:9  br label %for.body10; CHECK: entry:11; CHECK:   %flatten.tripcount = mul i32 20, 1012; CHECK:   br label %for.body13 14for.body:                                         ; preds = %entry, %for.inc615  %i.018 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]16  %mul = mul nuw nsw i32 %i.018, 2017  br label %for.body318; CHECK: for.body:19; CHECK:   %i.018 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]20; CHECK:   %mul = mul nuw nsw i32 %i.018, 2021; CHECK:   br label %for.body322 23for.body3:                                        ; preds = %for.body, %for.body324  %j.017 = phi i32 [ 0, %for.body ], [ %inc, %for.body3 ]25  %add = add nuw nsw i32 %j.017, %mul26  %arrayidx = getelementptr inbounds i16, ptr %A, i32 %add27  %0 = load i16, ptr %arrayidx, align 228  %conv16 = zext i16 %0 to i3229  %add4 = add i32 %conv16, %val30  %conv5 = trunc i32 %add4 to i1631  store i16 %conv5, ptr %arrayidx, align 232  %inc = add nuw nsw i32 %j.017, 133  %exitcond = icmp ne i32 %inc, 2034  br i1 %exitcond, label %for.body3, label %for.inc635; CHECK: for.body3:36; CHECK:   %j.017 = phi i32 [ 0, %for.body ]37; CHECK:   %add = add nuw nsw i32 %j.017, %mul38; CHECK:   %arrayidx = getelementptr inbounds i16, ptr %A, i32 %i.01839; CHECK:   %0 = load i16, ptr %arrayidx, align 240; CHECK:   %conv16 = zext i16 %0 to i3241; CHECK:   %add4 = add i32 %conv16, %val42; CHECK:   %conv5 = trunc i32 %add4 to i1643; CHECK:   store i16 %conv5, ptr %arrayidx, align 244; CHECK:   %inc = add nuw nsw i32 %j.017, 145; CHECK:   %exitcond = icmp ne i32 %inc, 2046; CHECK:   br label %for.inc647 48for.inc6:                                         ; preds = %for.body349  %inc7 = add nuw nsw i32 %i.018, 150  %exitcond19 = icmp ne i32 %inc7, 1051  br i1 %exitcond19, label %for.body, label %for.end852; CHECK: for.inc6:53; CHECK:   %inc7 = add nuw nsw i32 %i.018, 154; CHECK:   %exitcond19 = icmp ne i32 %inc7, %flatten.tripcount55; CHECK:   br i1 %exitcond19, label %for.body, label %for.end856 57for.end8:                                         ; preds = %for.inc658  ret i32 1059}60 61 62; CHECK-LABEL: test263; Same as above but non constant IV (which still cannot overflow)64define i32 @test2(i8 zeroext %I, i32 %val, ptr nocapture %A) {65entry:66  %conv = zext i8 %I to i3267  %cmp26 = icmp eq i8 %I, 068  br i1 %cmp26, label %for.end13, label %for.body.lr.ph.split.us69 70for.body.lr.ph.split.us:                          ; preds = %entry71  br label %for.body.us72; CHECK: for.body.lr.ph.split.us:73; CHECK:   %flatten.tripcount = mul i32 %conv, %conv74; CHECK:   br label %for.body.us75 76for.body.us:                                      ; preds = %for.cond2.for.inc11_crit_edge.us, %for.body.lr.ph.split.us77  %i.027.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc12.us, %for.cond2.for.inc11_crit_edge.us ]78  %mul.us = mul nuw nsw i32 %i.027.us, %conv79  br label %for.body6.us80; CHECK: for.body.us:81; CHECK:   %i.027.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc12.us, %for.cond2.for.inc11_crit_edge.us ]82; CHECK:   %mul.us = mul nuw nsw i32 %i.027.us, %conv83; CHECK:   br label %for.body6.us84 85for.body6.us:                                     ; preds = %for.body.us, %for.body6.us86  %j.025.us = phi i32 [ 0, %for.body.us ], [ %inc.us, %for.body6.us ]87  %add.us = add nuw nsw i32 %j.025.us, %mul.us88  %arrayidx.us = getelementptr inbounds i16, ptr %A, i32 %add.us89  %0 = load i16, ptr %arrayidx.us, align 290  %conv823.us = zext i16 %0 to i3291  %add9.us = add i32 %conv823.us, %val92  %conv10.us = trunc i32 %add9.us to i1693  store i16 %conv10.us, ptr %arrayidx.us, align 294  %inc.us = add nuw nsw i32 %j.025.us, 195  %exitcond = icmp ne i32 %inc.us, %conv96  br i1 %exitcond, label %for.body6.us, label %for.cond2.for.inc11_crit_edge.us97; CHECK: for.body6.us:98; CHECK:   %j.025.us = phi i32 [ 0, %for.body.us ]99; CHECK:   %add.us = add nuw nsw i32 %j.025.us, %mul.us100; CHECK:   %arrayidx.us = getelementptr inbounds i16, ptr %A, i32 %i.027.us101; CHECK:   %0 = load i16, ptr %arrayidx.us, align 2102; CHECK:   %conv823.us = zext i16 %0 to i32103; CHECK:   %add9.us = add i32 %conv823.us, %val104; CHECK:   %conv10.us = trunc i32 %add9.us to i16105; CHECK:   store i16 %conv10.us, ptr %arrayidx.us, align 2106; CHECK:   %inc.us = add nuw nsw i32 %j.025.us, 1107; CHECK:   %exitcond = icmp ne i32 %inc.us, %conv108; CHECK:   br label %for.cond2.for.inc11_crit_edge.us109 110for.cond2.for.inc11_crit_edge.us:                 ; preds = %for.body6.us111  %inc12.us = add nuw nsw i32 %i.027.us, 1112  %exitcond28 = icmp ne i32 %inc12.us, %conv113  br i1 %exitcond28, label %for.body.us, label %for.end13.loopexit114; CHECK: for.cond2.for.inc11_crit_edge.us:                 ; preds = %for.body6.us115; CHECK:   %inc12.us = add nuw nsw i32 %i.027.us, 1116; CHECK:   %exitcond28 = icmp ne i32 %inc12.us, %flatten.tripcount117; CHECK:   br i1 %exitcond28, label %for.body.us, label %for.end13.loopexit118 119for.end13.loopexit:                               ; preds = %for.cond2.for.inc11_crit_edge.us120  br label %for.end13121 122for.end13:                                        ; preds = %for.end13.loopexit, %entry123  %i.0.lcssa = phi i32 [ 0, %entry ], [ %conv, %for.end13.loopexit ]124  ret i32 %i.0.lcssa125}126 127 128; CHECK-LABEL: test3129; Same as above, uses load to determine it can't overflow130define i32 @test3(i32 %N, i32 %val, ptr nocapture %A) local_unnamed_addr #0 {131entry:132  %cmp21 = icmp eq i32 %N, 0133  br i1 %cmp21, label %for.end8, label %for.body.lr.ph.split.us134 135for.body.lr.ph.split.us:                          ; preds = %entry136  br label %for.body.us137; CHECK: for.body.lr.ph.split.us:138; CHECK:   %flatten.tripcount = mul i32 %N, %N139; CHECK:   br label %for.body.us140 141for.body.us:                                      ; preds = %for.cond1.for.inc6_crit_edge.us, %for.body.lr.ph.split.us142  %i.022.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc7.us, %for.cond1.for.inc6_crit_edge.us ]143  %mul.us = mul i32 %i.022.us, %N144  br label %for.body3.us145; CHECK: for.body.us:146; CHECK:   %i.022.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc7.us, %for.cond1.for.inc6_crit_edge.us ]147; CHECK:   %mul.us = mul i32 %i.022.us, %N148; CHECK:   br label %for.body3.us149 150for.body3.us:                                     ; preds = %for.body.us, %for.body3.us151  %j.020.us = phi i32 [ 0, %for.body.us ], [ %inc.us, %for.body3.us ]152  %add.us = add i32 %j.020.us, %mul.us153  %arrayidx.us = getelementptr inbounds i16, ptr %A, i32 %add.us154  %0 = load i16, ptr %arrayidx.us, align 2155  %conv18.us = zext i16 %0 to i32156  %add4.us = add i32 %conv18.us, %val157  %conv5.us = trunc i32 %add4.us to i16158  store i16 %conv5.us, ptr %arrayidx.us, align 2159  %inc.us = add nuw i32 %j.020.us, 1160  %exitcond = icmp ne i32 %inc.us, %N161  br i1 %exitcond, label %for.body3.us, label %for.cond1.for.inc6_crit_edge.us162; CHECK: for.body3.us:163; CHECK:   %j.020.us = phi i32 [ 0, %for.body.us ]164; CHECK:   %add.us = add i32 %j.020.us, %mul.us165; CHECK:   %arrayidx.us = getelementptr inbounds i16, ptr %A, i32 %i.022.us166; CHECK:   %0 = load i16, ptr %arrayidx.us, align 2167; CHECK:   %conv18.us = zext i16 %0 to i32168; CHECK:   %add4.us = add i32 %conv18.us, %val169; CHECK:   %conv5.us = trunc i32 %add4.us to i16170; CHECK:   store i16 %conv5.us, ptr %arrayidx.us, align 2171; CHECK:   %inc.us = add nuw i32 %j.020.us, 1172; CHECK:   %exitcond = icmp ne i32 %inc.us, %N173; CHECK:   br label %for.cond1.for.inc6_crit_edge.us174 175for.cond1.for.inc6_crit_edge.us:                  ; preds = %for.body3.us176  %inc7.us = add nuw i32 %i.022.us, 1177  %exitcond23 = icmp ne i32 %inc7.us, %N178  br i1 %exitcond23, label %for.body.us, label %for.end8.loopexit179; CHECK: for.cond1.for.inc6_crit_edge.us:180; CHECK:   %inc7.us = add nuw i32 %i.022.us, 1181; CHECK:   %exitcond23 = icmp ne i32 %inc7.us, %flatten.tripcount182; CHECK:   br i1 %exitcond23, label %for.body.us, label %for.end8.loopexit183 184for.end8.loopexit:                                ; preds = %for.cond1.for.inc6_crit_edge.us185  br label %for.end8186 187for.end8:                                         ; preds = %for.end8.loopexit, %entry188  %i.0.lcssa = phi i32 [ 0, %entry ], [ %N, %for.end8.loopexit ]189  ret i32 %i.0.lcssa190}191 192 193; CHECK-LABEL: test4194; Multiplication cannot overflow, so we can replace the original loop.195define void @test4(i16 zeroext %N, ptr nocapture %C, ptr nocapture readonly %A, i32 %scale) {196entry:197  %conv = zext i16 %N to i32198  %cmp30 = icmp eq i16 %N, 0199  br i1 %cmp30, label %for.cond.cleanup, label %for.body.lr.ph.split.us200; CHECK: entry:201; CHECK: %[[LIMIT:.*]] = zext i16 %N to i32202; CHECK: br i1 %{{.*}} label %for.cond.cleanup, label %for.body.lr.ph.split.us203 204for.body.lr.ph.split.us:                          ; preds = %entry205  br label %for.body.us206; CHECK: for.body.lr.ph.split.us:207; CHECK: %[[TRIPCOUNT:.*]] = mul i32 %[[LIMIT]], %[[LIMIT]]208; CHECK: br label %for.body.us209 210for.body.us:                                      ; preds = %for.cond2.for.cond.cleanup6_crit_edge.us, %for.body.lr.ph.split.us211  %i.031.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc15.us, %for.cond2.for.cond.cleanup6_crit_edge.us ]212  %mul.us = mul nuw nsw i32 %i.031.us, %conv213  br label %for.body7.us214; CHECK: for.body.us:215; CHECK: %[[OUTER_IV:.*]] = phi i32216; CHECK: br label %for.body7.us217 218for.body7.us:                                     ; preds = %for.body.us, %for.body7.us219; CHECK: for.body7.us:220  %j.029.us = phi i32 [ 0, %for.body.us ], [ %inc.us, %for.body7.us ]221  %add.us = add nuw nsw i32 %j.029.us, %mul.us222  %arrayidx.us = getelementptr inbounds i32, ptr %A, i32 %add.us223; CHECK: getelementptr inbounds i32, ptr %A, i32 %[[OUTER_IV]]224  %0 = load i32, ptr %arrayidx.us, align 4225  %mul9.us = mul nsw i32 %0, %scale226; CHECK: getelementptr inbounds i32, ptr %C, i32 %[[OUTER_IV]]227  %arrayidx13.us = getelementptr inbounds i32, ptr %C, i32 %add.us228  store i32 %mul9.us, ptr %arrayidx13.us, align 4229  %inc.us = add nuw nsw i32 %j.029.us, 1230  %exitcond = icmp ne i32 %inc.us, %conv231  br i1 %exitcond, label %for.body7.us, label %for.cond2.for.cond.cleanup6_crit_edge.us232; CHECK: br label %for.cond2.for.cond.cleanup6_crit_edge.us233 234for.cond2.for.cond.cleanup6_crit_edge.us:         ; preds = %for.body7.us235  %inc15.us = add nuw nsw i32 %i.031.us, 1236  %exitcond32 = icmp ne i32 %inc15.us, %conv237  br i1 %exitcond32, label %for.body.us, label %for.cond.cleanup.loopexit238; CHECK: for.cond2.for.cond.cleanup6_crit_edge.us:239; CHECK: br i1 %exitcond32, label %for.body.us, label %for.cond.cleanup.loopexit240 241for.cond.cleanup.loopexit:                        ; preds = %for.cond2.for.cond.cleanup6_crit_edge.us242  br label %for.cond.cleanup243; CHECK: for.cond.cleanup.loopexit:244; CHECK: br label %for.cond.cleanup245 246for.cond.cleanup:                                 ; preds = %for.cond.cleanup.loopexit, %entry247  ret void248; CHECK: for.cond.cleanup:249; CHECK: ret void250}251 252 253; CHECK-LABEL: test5254define i32 @test5(i8 zeroext %I, i16 zeroext %J) {255entry:256  %0 = lshr i8 %I, 1257  %div = zext i8 %0 to i32258  %cmp30 = icmp eq i8 %0, 0259  br i1 %cmp30, label %for.cond.cleanup, label %for.body.lr.ph260 261for.body.lr.ph:                                   ; preds = %entry262  %1 = lshr i16 %J, 1263  %div5 = zext i16 %1 to i32264  %cmp627 = icmp eq i16 %1, 0265  br i1 %cmp627, label %for.body.lr.ph.split, label %for.body.lr.ph.split.us266 267for.body.lr.ph.split.us:                          ; preds = %for.body.lr.ph268  br label %for.body.us269; CHECK: for.body.lr.ph.split.us:270; CHECK:   %flatten.tripcount = mul i32 %div5, %div271; CHECK:   br label %for.body.us272 273for.body.us:                                      ; preds = %for.cond3.for.cond.cleanup8_crit_edge.us, %for.body.lr.ph.split.us274  %i.032.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc13.us, %for.cond3.for.cond.cleanup8_crit_edge.us ]275  %x.031.us = phi i32 [ 1, %for.body.lr.ph.split.us ], [ %xor.us.lcssa, %for.cond3.for.cond.cleanup8_crit_edge.us ]276  br label %for.body9.us277; CHECK: for.body.us:278; CHECK:   %i.032.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc13.us, %for.cond3.for.cond.cleanup8_crit_edge.us ]279; CHECK:   %x.031.us = phi i32 [ 1, %for.body.lr.ph.split.us ], [ %xor.us.lcssa, %for.cond3.for.cond.cleanup8_crit_edge.us ]280; CHECK:   br label %for.body9.us281 282for.body9.us:                                     ; preds = %for.body.us, %for.body9.us283  %j.029.us = phi i32 [ 0, %for.body.us ], [ %inc.us, %for.body9.us ]284  %x.128.us = phi i32 [ %x.031.us, %for.body.us ], [ %xor.us, %for.body9.us ]285  %call.us = tail call i32 @func(i32 1)286  %sub.us = sub nsw i32 %call.us, %x.128.us287  %xor.us = xor i32 %sub.us, %x.128.us288  %inc.us = add nuw nsw i32 %j.029.us, 1289  %cmp6.us = icmp ult i32 %inc.us, %div5290  br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us291; CHECK: for.body9.us:292; CHECK:   %j.029.us = phi i32 [ 0, %for.body.us ]293; CHECK:   %x.128.us = phi i32 [ %x.031.us, %for.body.us ]294; CHECK:   %call.us = tail call i32 @func(i32 1)295; CHECK:   %sub.us = sub nsw i32 %call.us, %x.128.us296; CHECK:   %xor.us = xor i32 %sub.us, %x.128.us297; CHECK:   %inc.us = add nuw nsw i32 %j.029.us, 1298; CHECK:   %cmp6.us = icmp ult i32 %inc.us, %div5299; CHECK:   br label %for.cond3.for.cond.cleanup8_crit_edge.us300 301for.cond3.for.cond.cleanup8_crit_edge.us:         ; preds = %for.body9.us302  %xor.us.lcssa = phi i32 [ %xor.us, %for.body9.us ]303  %inc13.us = add nuw nsw i32 %i.032.us, 1304  %cmp.us = icmp ult i32 %inc13.us, %div305  br i1 %cmp.us, label %for.body.us, label %for.cond.cleanup.loopexit306; CHECK: for.cond3.for.cond.cleanup8_crit_edge.us:307; CHECK:   %xor.us.lcssa = phi i32 [ %xor.us, %for.body9.us ]308; CHECK:   %inc13.us = add nuw nsw i32 %i.032.us, 1309; CHECK:   %cmp.us = icmp ult i32 %inc13.us, %flatten.tripcount310; CHECK:   br i1 %cmp.us, label %for.body.us, label %for.cond.cleanup.loopexit311 312for.body.lr.ph.split:                             ; preds = %for.body.lr.ph313  br label %for.body314 315for.cond.cleanup.loopexit:                        ; preds = %for.cond3.for.cond.cleanup8_crit_edge.us316  %xor.us.lcssa.lcssa = phi i32 [ %xor.us.lcssa, %for.cond3.for.cond.cleanup8_crit_edge.us ]317  br label %for.cond.cleanup318 319for.cond.cleanup.loopexit34:                      ; preds = %for.body320  br label %for.cond.cleanup321 322for.cond.cleanup:                                 ; preds = %for.cond.cleanup.loopexit34, %for.cond.cleanup.loopexit, %entry323  %x.0.lcssa = phi i32 [ 1, %entry ], [ %xor.us.lcssa.lcssa, %for.cond.cleanup.loopexit ], [ 1, %for.cond.cleanup.loopexit34 ]324  ret i32 %x.0.lcssa325 326for.body:                                         ; preds = %for.body.lr.ph.split, %for.body327  %i.032 = phi i32 [ 0, %for.body.lr.ph.split ], [ %inc13, %for.body ]328  %inc13 = add nuw nsw i32 %i.032, 1329  %cmp = icmp ult i32 %inc13, %div330  br i1 %cmp, label %for.body, label %for.cond.cleanup.loopexit34331}332 333 334; CHECK-LABEL: test6335define i32 @test6(i8 zeroext %I, i16 zeroext %J) {336entry:337  %0 = lshr i8 %I, 1338  %div = zext i8 %0 to i32339  %cmp30 = icmp eq i8 %0, 0340  br i1 %cmp30, label %for.cond.cleanup, label %for.body.lr.ph341 342for.body.lr.ph:                                   ; preds = %entry343  %1 = lshr i16 %J, 1344  %div5 = zext i16 %1 to i32345  %cmp627 = icmp eq i16 %1, 0346  br i1 %cmp627, label %for.body.lr.ph.split, label %for.body.lr.ph.split.us347 348for.body.lr.ph.split.us:                          ; preds = %for.body.lr.ph349  br label %for.body.us350; CHECK: for.body.lr.ph.split.us:351; CHECK:   %flatten.tripcount = mul i32 %div5, %div352; CHECK:   br label %for.body.us353 354for.body.us:                                      ; preds = %for.cond3.for.cond.cleanup8_crit_edge.us, %for.body.lr.ph.split.us355  %i.032.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc13.us, %for.cond3.for.cond.cleanup8_crit_edge.us ]356  %x.031.us = phi i32 [ 1, %for.body.lr.ph.split.us ], [ %xor.us.lcssa, %for.cond3.for.cond.cleanup8_crit_edge.us ]357  %mul.us = mul nuw nsw i32 %i.032.us, %div5358  br label %for.body9.us359; CHECK: for.body.us:360; CHECK:   %i.032.us = phi i32 [ 0, %for.body.lr.ph.split.us ], [ %inc13.us, %for.cond3.for.cond.cleanup8_crit_edge.us ]361; CHECK:   %x.031.us = phi i32 [ 1, %for.body.lr.ph.split.us ], [ %xor.us.lcssa, %for.cond3.for.cond.cleanup8_crit_edge.us ]362; CHECK:   %mul.us = mul nuw nsw i32 %i.032.us, %div5363; CHECK:   br label %for.body9.us364 365for.body9.us:                                     ; preds = %for.body.us, %for.body9.us366  %j.029.us = phi i32 [ 0, %for.body.us ], [ %inc.us, %for.body9.us ]367  %x.128.us = phi i32 [ %x.031.us, %for.body.us ], [ %xor.us, %for.body9.us ]368  %add.us = add nuw nsw i32 %j.029.us, %mul.us369  %call.us = tail call i32 @func(i32 %add.us)370  %sub.us = sub nsw i32 %call.us, %x.128.us371  %xor.us = xor i32 %sub.us, %x.128.us372  %inc.us = add nuw nsw i32 %j.029.us, 1373  %cmp6.us = icmp ult i32 %inc.us, %div5374  br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us375; CHECK: for.body9.us:376; CHECK:   %j.029.us = phi i32 [ 0, %for.body.us ]377; CHECK:   %x.128.us = phi i32 [ %x.031.us, %for.body.us ]378; CHECK:   %add.us = add nuw nsw i32 %j.029.us, %mul.us379; CHECK:   %call.us = tail call i32 @func(i32 %i.032.us)380; CHECK:   %sub.us = sub nsw i32 %call.us, %x.128.us381; CHECK:   %xor.us = xor i32 %sub.us, %x.128.us382; CHECK:   %inc.us = add nuw nsw i32 %j.029.us, 1383; CHECK:   %cmp6.us = icmp ult i32 %inc.us, %div5384; CHECK:   br label %for.cond3.for.cond.cleanup8_crit_edge.us385 386for.cond3.for.cond.cleanup8_crit_edge.us:         ; preds = %for.body9.us387  %xor.us.lcssa = phi i32 [ %xor.us, %for.body9.us ]388  %inc13.us = add nuw nsw i32 %i.032.us, 1389  %cmp.us = icmp ult i32 %inc13.us, %div390  br i1 %cmp.us, label %for.body.us, label %for.cond.cleanup.loopexit391; CHECK: for.cond3.for.cond.cleanup8_crit_edge.us:392; CHECK:   %xor.us.lcssa = phi i32 [ %xor.us, %for.body9.us ]393; CHECK:   %inc13.us = add nuw nsw i32 %i.032.us, 1394; CHECK:   %cmp.us = icmp ult i32 %inc13.us, %flatten.tripcount395; CHECK:   br i1 %cmp.us, label %for.body.us, label %for.cond.cleanup.loopexit396 397for.body.lr.ph.split:                             ; preds = %for.body.lr.ph398  br label %for.body399 400for.cond.cleanup.loopexit:                        ; preds = %for.cond3.for.cond.cleanup8_crit_edge.us401  %xor.us.lcssa.lcssa = phi i32 [ %xor.us.lcssa, %for.cond3.for.cond.cleanup8_crit_edge.us ]402  br label %for.cond.cleanup403 404for.cond.cleanup.loopexit34:                      ; preds = %for.body405  br label %for.cond.cleanup406 407for.cond.cleanup:                                 ; preds = %for.cond.cleanup.loopexit34, %for.cond.cleanup.loopexit, %entry408  %x.0.lcssa = phi i32 [ 1, %entry ], [ %xor.us.lcssa.lcssa, %for.cond.cleanup.loopexit ], [ 1, %for.cond.cleanup.loopexit34 ]409  ret i32 %x.0.lcssa410 411for.body:                                         ; preds = %for.body.lr.ph.split, %for.body412  %i.032 = phi i32 [ 0, %for.body.lr.ph.split ], [ %inc13, %for.body ]413  %inc13 = add nuw nsw i32 %i.032, 1414  %cmp = icmp ult i32 %inc13, %div415  br i1 %cmp, label %for.body, label %for.cond.cleanup.loopexit34416}417 418; CHECK-LABEL: test7419; Various inner phis and conditions which we can still work with420define signext i16 @test7(i32 %I, i32 %J, ptr nocapture readonly %C, i16 signext %limit) {421entry:422  %cmp43 = icmp eq i32 %J, 0423  br i1 %cmp43, label %for.end17, label %for.body.lr.ph424 425for.body.lr.ph:                                   ; preds = %entry426  %conv = sext i16 %limit to i32427  br label %for.body.us428; CHECK: for.body.lr.ph:429; CHECK:   %conv = sext i16 %limit to i32430; CHECK:   %flatten.tripcount = mul i32 %J, %J431; CHECK:   br label %for.body.us432 433for.body.us:                                      ; preds = %for.cond1.for.inc15_crit_edge.us, %for.body.lr.ph434  %i.047.us = phi i32 [ 0, %for.body.lr.ph ], [ %inc16.us, %for.cond1.for.inc15_crit_edge.us ]435  %ret.046.us = phi i16 [ 0, %for.body.lr.ph ], [ %ret.2.us.lcssa, %for.cond1.for.inc15_crit_edge.us ]436  %prev.045.us = phi i32 [ 0, %for.body.lr.ph ], [ %.lcssa, %for.cond1.for.inc15_crit_edge.us ]437  %tmp.044.us = phi i32 [ 0, %for.body.lr.ph ], [ %tmp.2.us.lcssa, %for.cond1.for.inc15_crit_edge.us ]438  %mul.us = mul i32 %i.047.us, %J439  br label %for.body3.us440; CHECK: for.body.us:441; CHECK:   %i.047.us = phi i32 [ 0, %for.body.lr.ph ], [ %inc16.us, %for.cond1.for.inc15_crit_edge.us ]442; CHECK:   %ret.046.us = phi i16 [ 0, %for.body.lr.ph ], [ %ret.2.us.lcssa, %for.cond1.for.inc15_crit_edge.us ]443; CHECK:   %prev.045.us = phi i32 [ 0, %for.body.lr.ph ], [ %.lcssa, %for.cond1.for.inc15_crit_edge.us ]444; CHECK:   %tmp.044.us = phi i32 [ 0, %for.body.lr.ph ], [ %tmp.2.us.lcssa, %for.cond1.for.inc15_crit_edge.us ]445; CHECK:   %mul.us = mul i32 %i.047.us, %J446; CHECK:   br label %for.body3.us447 448for.body3.us:                                     ; preds = %for.body.us, %if.end.us449  %j.040.us = phi i32 [ 0, %for.body.us ], [ %inc.us, %if.end.us ]450  %ret.139.us = phi i16 [ %ret.046.us, %for.body.us ], [ %ret.2.us, %if.end.us ]451  %prev.138.us = phi i32 [ %prev.045.us, %for.body.us ], [ %0, %if.end.us ]452  %tmp.137.us = phi i32 [ %tmp.044.us, %for.body.us ], [ %tmp.2.us, %if.end.us ]453  %add.us = add i32 %j.040.us, %mul.us454  %arrayidx.us = getelementptr inbounds i32, ptr %C, i32 %add.us455  %0 = load i32, ptr %arrayidx.us, align 4456  %add4.us = add nsw i32 %0, %tmp.137.us457  %cmp5.us = icmp sgt i32 %add4.us, %conv458  br i1 %cmp5.us, label %if.then.us, label %if.else.us459; CHECK: for.body3.us:460; CHECK:   %j.040.us = phi i32 [ 0, %for.body.us ]461; CHECK:   %ret.139.us = phi i16 [ %ret.046.us, %for.body.us ]462; CHECK:   %prev.138.us = phi i32 [ %prev.045.us, %for.body.us ]463; CHECK:   %tmp.137.us = phi i32 [ %tmp.044.us, %for.body.us ]464; CHECK:   %add.us = add i32 %j.040.us, %mul.us465; CHECK:   %arrayidx.us = getelementptr inbounds i32, ptr %C, i32 %i.047.us466; CHECK:   %0 = load i32, ptr %arrayidx.us, align 4467; CHECK:   %add4.us = add nsw i32 %0, %tmp.137.us468; CHECK:   %cmp5.us = icmp sgt i32 %add4.us, %conv469; CHECK:   br i1 %cmp5.us, label %if.then.us, label %if.else.us470 471if.else.us:                                       ; preds = %for.body3.us472  %cmp10.us = icmp sgt i32 %0, %prev.138.us473  %cond.us = zext i1 %cmp10.us to i32474  %conv1235.us = zext i16 %ret.139.us to i32475  %add13.us = add nuw nsw i32 %cond.us, %conv1235.us476  br label %if.end.us477; CHECK: if.else.us:478; CHECK:   %cmp10.us = icmp sgt i32 %0, %prev.138.us479; CHECK:   %cond.us = zext i1 %cmp10.us to i32480; CHECK:   %conv1235.us = zext i16 %ret.139.us to i32481; CHECK:   %add13.us = add nuw nsw i32 %cond.us, %conv1235.us482; CHECK:   br label %if.end.us483 484if.then.us:                                       ; preds = %for.body3.us485  %conv7.us = sext i16 %ret.139.us to i32486  %add8.us = add nsw i32 %conv7.us, 10487  br label %if.end.us488; CHECK: if.then.us:489; CHECK:   %conv7.us = sext i16 %ret.139.us to i32490; CHECK:   %add8.us = add nsw i32 %conv7.us, 10491; CHECK:   br label %if.end.us492 493if.end.us:                                        ; preds = %if.then.us, %if.else.us494  %tmp.2.us = phi i32 [ 0, %if.then.us ], [ %add4.us, %if.else.us ]495  %ret.2.in.us = phi i32 [ %add8.us, %if.then.us ], [ %add13.us, %if.else.us ]496  %ret.2.us = trunc i32 %ret.2.in.us to i16497  %inc.us = add nuw i32 %j.040.us, 1498  %exitcond = icmp ne i32 %inc.us, %J499  br i1 %exitcond, label %for.body3.us, label %for.cond1.for.inc15_crit_edge.us500; CHECK: if.end.us:501; CHECK:   %tmp.2.us = phi i32 [ 0, %if.then.us ], [ %add4.us, %if.else.us ]502; CHECK:   %ret.2.in.us = phi i32 [ %add8.us, %if.then.us ], [ %add13.us, %if.else.us ]503; CHECK:   %ret.2.us = trunc i32 %ret.2.in.us to i16504; CHECK:   %inc.us = add nuw i32 %j.040.us, 1505; CHECK:   %exitcond = icmp ne i32 %inc.us, %J506; CHECK:   br label %for.cond1.for.inc15_crit_edge.us507 508for.cond1.for.inc15_crit_edge.us:                 ; preds = %if.end.us509  %tmp.2.us.lcssa = phi i32 [ %tmp.2.us, %if.end.us ]510  %ret.2.us.lcssa = phi i16 [ %ret.2.us, %if.end.us ]511  %.lcssa = phi i32 [ %0, %if.end.us ]512  %inc16.us = add nuw i32 %i.047.us, 1513  %exitcond49 = icmp ne i32 %inc16.us, %J514  br i1 %exitcond49, label %for.body.us, label %for.end17.loopexit515; CHECK: for.cond1.for.inc15_crit_edge.us:516; CHECK:   %tmp.2.us.lcssa = phi i32 [ %tmp.2.us, %if.end.us ]517; CHECK:   %ret.2.us.lcssa = phi i16 [ %ret.2.us, %if.end.us ]518; CHECK:   %.lcssa = phi i32 [ %0, %if.end.us ]519; CHECK:   %inc16.us = add nuw i32 %i.047.us, 1520; CHECK:   %exitcond49 = icmp ne i32 %inc16.us, %flatten.tripcount521; CHECK:   br i1 %exitcond49, label %for.body.us, label %for.end17.loopexit522 523for.end17.loopexit:                               ; preds = %for.cond1.for.inc15_crit_edge.us524  %ret.2.us.lcssa.lcssa = phi i16 [ %ret.2.us.lcssa, %for.cond1.for.inc15_crit_edge.us ]525  br label %for.end17526 527for.end17:                                        ; preds = %for.end17.loopexit, %entry528  %ret.0.lcssa = phi i16 [ 0, %entry ], [ %ret.2.us.lcssa.lcssa, %for.end17.loopexit ]529  ret i16 %ret.0.lcssa530}531 532; CHECK-LABEL: test8533; Same as test1, but with different continue block order534; (uses icmp eq and loops on false)535define i32 @test8(i32 %val, ptr nocapture %A) {536entry:537  br label %for.body538; CHECK: entry:539; CHECK:   %flatten.tripcount = mul i32 20, 10540; CHECK:   br label %for.body541 542for.body:                                         ; preds = %entry, %for.inc6543  %i.018 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]544  %mul = mul nuw nsw i32 %i.018, 20545  br label %for.body3546; CHECK: for.body:547; CHECK:   %i.018 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]548; CHECK:   %mul = mul nuw nsw i32 %i.018, 20549; CHECK:   br label %for.body3550 551for.body3:                                        ; preds = %for.body, %for.body3552  %j.017 = phi i32 [ 0, %for.body ], [ %inc, %for.body3 ]553  %add = add nuw nsw i32 %j.017, %mul554  %arrayidx = getelementptr inbounds i16, ptr %A, i32 %add555  %0 = load i16, ptr %arrayidx, align 2556  %conv16 = zext i16 %0 to i32557  %add4 = add i32 %conv16, %val558  %conv5 = trunc i32 %add4 to i16559  store i16 %conv5, ptr %arrayidx, align 2560  %inc = add nuw nsw i32 %j.017, 1561  %exitcond = icmp eq i32 %inc, 20562  br i1 %exitcond, label %for.inc6, label %for.body3563; CHECK: for.body3:564; CHECK:   %j.017 = phi i32 [ 0, %for.body ]565; CHECK:   %add = add nuw nsw i32 %j.017, %mul566; CHECK:   %arrayidx = getelementptr inbounds i16, ptr %A, i32 %i.018567; CHECK:   %0 = load i16, ptr %arrayidx, align 2568; CHECK:   %conv16 = zext i16 %0 to i32569; CHECK:   %add4 = add i32 %conv16, %val570; CHECK:   %conv5 = trunc i32 %add4 to i16571; CHECK:   store i16 %conv5, ptr %arrayidx, align 2572; CHECK:   %inc = add nuw nsw i32 %j.017, 1573; CHECK:   %exitcond = icmp eq i32 %inc, 20574; CHECK:   br label %for.inc6575 576for.inc6:                                         ; preds = %for.body3577  %inc7 = add nuw nsw i32 %i.018, 1578  %exitcond19 = icmp eq i32 %inc7, 10579  br i1 %exitcond19, label %for.end8, label %for.body580; CHECK: for.inc6:581; CHECK:   %inc7 = add nuw nsw i32 %i.018, 1582; CHECK:   %exitcond19 = icmp eq i32 %inc7, %flatten.tripcount583; CHECK:   br i1 %exitcond19, label %for.end8, label %for.body584 585for.end8:                                         ; preds = %for.inc6586  ret i32 10587}588 589; When the inner loop trip count is a constant and the step590; is 1, the InstCombine pass causes the transformation e.g.591; icmp ult i32 %inc, 20 -> icmp ult i32 %j, 19. This doesn't592; match the pattern (OuterPHI * InnerTripCount) + InnerPHI but593; we should still flatten the loop as the compare is removed594; later anyway.595define i32 @test9(ptr nocapture %A) {596entry:597  br label %for.cond1.preheader598; CHECK-LABEL: test9599; CHECK: entry:600; CHECK: %flatten.tripcount = mul i32 20, 11601; CHECK: br label %for.cond1.preheader602 603for.cond1.preheader:604  %i.017 = phi i32 [ 0, %entry ], [ %inc6, %for.cond.cleanup3 ]605  %mul = mul i32 %i.017, 20606  br label %for.body4607; CHECK: for.cond1.preheader:608; CHECK:   %i.017 = phi i32 [ 0, %entry ], [ %inc6, %for.cond.cleanup3 ]609; CHECK:   %mul = mul i32 %i.017, 20610; CHECK:   br label %for.body4611 612for.cond.cleanup3:613  %inc6 = add i32 %i.017, 1614  %cmp = icmp ult i32 %inc6, 11615  br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup616; CHECK: for.cond.cleanup3:617; CHECK:   %inc6 = add i32 %i.017, 1618; CHECK:   %cmp = icmp ult i32 %inc6, %flatten.tripcount619; CHECK:   br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup620 621for.body4:622  %j.016 = phi i32 [ 0, %for.cond1.preheader ], [ %inc, %for.body4 ]623  %add = add i32 %j.016, %mul624  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %add625  store i32 30, ptr %arrayidx, align 4626  %inc = add nuw nsw i32 %j.016, 1627  %cmp2 = icmp ult i32 %j.016, 19628  br i1 %cmp2, label %for.body4, label %for.cond.cleanup3629; CHECK: for.body4630; CHECK:   %j.016 = phi i32 [ 0, %for.cond1.preheader ]631; CHECK:   %add = add i32 %j.016, %mul632; CHECK:   %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.017633; CHECK:   store i32 30, ptr %arrayidx, align 4634; CHECK:   %inc = add nuw nsw i32 %j.016, 1635; CHECK:   %cmp2 = icmp ult i32 %j.016, 19636; CHECK:   br label %for.cond.cleanup3637 638for.cond.cleanup:639  %0 = load i32, ptr %A, align 4640  ret i32 %0641}642 643declare i32 @func(i32)644 645