1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -loop-rotate -o - -verify-loop-info -verify-dom-info | FileCheck %s 3 4@d = external global i64, align 8 5@f = external global i32, align 4 6@g = external global i32, align 4 7@i = external global i32, align 4 8@h = external global i32, align 4 9 10define i32 @o() #0 { 11; CHECK-LABEL: @o( 12; CHECK-NEXT: [[TMP1:%.*]] = alloca [1 x i32], align 4 13; CHECK-NEXT: [[TMP2:%.*]] = load i8*, i8** bitcast (i64* @d to i8**), align 8 14; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* @f, align 4 15; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0 16; CHECK-NEXT: br i1 [[TMP4]], label [[TMP17:%.*]], label [[DOTLR_PH4:%.*]] 17; CHECK: .lr.ph4: 18; CHECK-NEXT: br label [[TMP5:%.*]] 19; CHECK: 5: 20; CHECK-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP3]], [[DOTLR_PH4]] ], [ [[TMP15:%.*]], [[M_EXIT:%.*]] ] 21; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 [[TMP6]], 4 22; CHECK-NEXT: [[TMP8:%.*]] = zext i1 [[TMP7]] to i32 23; CHECK-NEXT: store i32 [[TMP8]], i32* @g, align 4 24; CHECK-NEXT: [[TMP9:%.*]] = bitcast [1 x i32]* [[TMP1]] to i8* 25; CHECK-NEXT: [[TMP10:%.*]] = call i32 @n(i8* nonnull [[TMP9]], i8* [[TMP2]]) 26; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], 0 27; CHECK-NEXT: br i1 [[TMP11]], label [[THREAD_PRE_SPLIT:%.*]], label [[DOT_CRIT_EDGE:%.*]] 28; CHECK: thread-pre-split: 29; CHECK-NEXT: [[DOTPR:%.*]] = load i32, i32* @i, align 4 30; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i32 [[DOTPR]], 0 31; CHECK-NEXT: br i1 [[TMP12]], label [[M_EXIT]], label [[DOTLR_PH:%.*]] 32; CHECK: .lr.ph: 33; CHECK-NEXT: br label [[TMP13:%.*]] 34; CHECK: 13: 35; CHECK-NEXT: [[DOT11:%.*]] = phi i32 [ undef, [[DOTLR_PH]] ], [ [[TMP14:%.*]], [[J_EXIT_I:%.*]] ] 36; CHECK-NEXT: callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"() #[[ATTR1:[0-9]+]] 37; CHECK-NEXT: to label [[J_EXIT_I]] [label %.m.exit_crit_edge] 38; CHECK: j.exit.i: 39; CHECK-NEXT: [[TMP14]] = tail call i32 asm "", "={ax},~{dirflag},~{fpsr},~{flags}"() #[[ATTR2:[0-9]+]] 40; CHECK-NEXT: br i1 [[TMP12]], label [[DOTM_EXIT_CRIT_EDGE2:%.*]], label [[TMP13]] 41; CHECK: .m.exit_crit_edge: 42; CHECK-NEXT: [[SPLIT:%.*]] = phi i32 [ [[DOT11]], [[TMP13]] ] 43; CHECK-NEXT: br label [[M_EXIT]] 44; CHECK: .m.exit_crit_edge2: 45; CHECK-NEXT: [[SPLIT3:%.*]] = phi i32 [ [[TMP14]], [[J_EXIT_I]] ] 46; CHECK-NEXT: br label [[M_EXIT]] 47; CHECK: m.exit: 48; CHECK-NEXT: [[DOT1_LCSSA:%.*]] = phi i32 [ [[SPLIT]], [[DOTM_EXIT_CRIT_EDGE:%.*]] ], [ [[SPLIT3]], [[DOTM_EXIT_CRIT_EDGE2]] ], [ undef, [[THREAD_PRE_SPLIT]] ] 49; CHECK-NEXT: store i32 [[DOT1_LCSSA]], i32* @h, align 4 50; CHECK-NEXT: [[TMP15]] = load i32, i32* @f, align 4 51; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0 52; CHECK-NEXT: br i1 [[TMP16]], label [[DOT_CRIT_EDGE5:%.*]], label [[TMP5]] 53; CHECK: ._crit_edge: 54; CHECK-NEXT: br label [[TMP17]] 55; CHECK: ._crit_edge5: 56; CHECK-NEXT: br label [[TMP17]] 57; CHECK: 17: 58; CHECK-NEXT: ret i32 undef 59; 60 %1 = alloca [1 x i32], align 4 61 %2 = load i8*, i8** bitcast (i64* @d to i8**), align 8 62 br label %3 63 64; <label>:3: ; preds = %m.exit, %0 65 %4 = load i32, i32* @f, align 4 66 %5 = icmp eq i32 %4, 0 67 br i1 %5, label %16, label %6 68 69; <label>:6: ; preds = %3 70 %7 = icmp ult i32 %4, 4 71 %8 = zext i1 %7 to i32 72 store i32 %8, i32* @g, align 4 73 %9 = bitcast [1 x i32]* %1 to i8* 74 %10 = call i32 @n(i8* nonnull %9, i8* %2) 75 %11 = icmp eq i32 %10, 0 76 br i1 %11, label %thread-pre-split, label %16 77 78thread-pre-split: ; preds = %6 79 %.pr = load i32, i32* @i, align 4 80 br label %12 81 82; <label>:12: ; preds = %j.exit.i, %thread-pre-split 83 %.1 = phi i32 [ %15, %j.exit.i ], [ undef, %thread-pre-split ] 84 %13 = icmp eq i32 %.pr, 0 85 br i1 %13, label %m.exit, label %14 86 87; <label>:14: ; preds = %12 88 callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"() #1 89 to label %j.exit.i [label %m.exit] 90 91j.exit.i: ; preds = %14 92 %15 = tail call i32 asm "", "={ax},~{dirflag},~{fpsr},~{flags}"() #2 93 br label %12 94 95m.exit: ; preds = %14, %12 96 %.1.lcssa = phi i32 [ %.1, %14 ], [ %.1, %12 ] 97 store i32 %.1.lcssa, i32* @h, align 4 98 br label %3 99 100; <label>:16: ; preds = %6, %3 101 ret i32 undef 102} 103 104declare i32 @n(i8*, i8*) #0 105 106attributes #0 = { "use-soft-float"="false" } 107attributes #1 = { nounwind } 108attributes #2 = { nounwind readnone } 109