1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s 3 4; No overflow flags, same type width. 5define i32 @test_01(ptr %p, i64 %len, i32 %x) { 6; CHECK-LABEL: test_01: 7; CHECK: # %bb.0: # %entry 8; CHECK-NEXT: addq $-4, %rdi 9; CHECK-NEXT: .p2align 4 10; CHECK-NEXT: .LBB0_1: # %loop 11; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 12; CHECK-NEXT: subq $1, %rsi 13; CHECK-NEXT: jb .LBB0_4 14; CHECK-NEXT: # %bb.2: # %backedge 15; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 16; CHECK-NEXT: cmpl %edx, (%rdi) 17; CHECK-NEXT: leaq 4(%rdi), %rdi 18; CHECK-NEXT: jne .LBB0_1 19; CHECK-NEXT: # %bb.3: # %failure 20; CHECK-NEXT: .LBB0_4: # %exit 21; CHECK-NEXT: movl $-1, %eax 22; CHECK-NEXT: retq 23entry: 24 %scevgep = getelementptr i32, ptr %p, i64 -1 25 br label %loop 26 27loop: ; preds = %backedge, %entry 28 %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ] 29 %iv.next = add i64 %iv, 1 30 %cond_1 = icmp eq i64 %iv, %len 31 br i1 %cond_1, label %exit, label %backedge 32 33backedge: ; preds = %loop 34 %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv 35 %loaded = load atomic i32, ptr %scevgep1 unordered, align 4 36 %cond_2 = icmp eq i32 %loaded, %x 37 br i1 %cond_2, label %failure, label %loop 38 39exit: ; preds = %loop 40 ret i32 -1 41 42failure: ; preds = %backedge 43 unreachable 44} 45 46; nsw flag, same type width. 47define i32 @test_02(ptr %p, i64 %len, i32 %x) { 48; CHECK-LABEL: test_02: 49; CHECK: # %bb.0: # %entry 50; CHECK-NEXT: addq $-4, %rdi 51; CHECK-NEXT: .p2align 4 52; CHECK-NEXT: .LBB1_1: # %loop 53; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 54; CHECK-NEXT: subq $1, %rsi 55; CHECK-NEXT: jb .LBB1_4 56; CHECK-NEXT: # %bb.2: # %backedge 57; CHECK-NEXT: # in Loop: Header=BB1_1 Depth=1 58; CHECK-NEXT: cmpl %edx, (%rdi) 59; CHECK-NEXT: leaq 4(%rdi), %rdi 60; CHECK-NEXT: jne .LBB1_1 61; CHECK-NEXT: # %bb.3: # %failure 62; CHECK-NEXT: .LBB1_4: # %exit 63; CHECK-NEXT: movl $-1, %eax 64; CHECK-NEXT: retq 65entry: 66 %scevgep = getelementptr i32, ptr %p, i64 -1 67 br label %loop 68 69loop: ; preds = %backedge, %entry 70 %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ] 71 %iv.next = add nsw i64 %iv, 1 72 %cond_1 = icmp eq i64 %iv, %len 73 br i1 %cond_1, label %exit, label %backedge 74 75backedge: ; preds = %loop 76 %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv 77 %loaded = load atomic i32, ptr %scevgep1 unordered, align 4 78 %cond_2 = icmp eq i32 %loaded, %x 79 br i1 %cond_2, label %failure, label %loop 80 81exit: ; preds = %loop 82 ret i32 -1 83 84failure: ; preds = %backedge 85 unreachable 86} 87 88; nsw flag, optimization is possible because memory instruction is dominated by loop-exiting check against iv.next. 89define i32 @test_02_nopoison(ptr %p, i64 %len, i32 %x) { 90; CHECK-LABEL: test_02_nopoison: 91; CHECK: # %bb.0: # %entry 92; CHECK-NEXT: addq $-4, %rdi 93; CHECK-NEXT: .p2align 4 94; CHECK-NEXT: .LBB2_1: # %loop 95; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 96; CHECK-NEXT: subq $1, %rsi 97; CHECK-NEXT: jb .LBB2_4 98; CHECK-NEXT: # %bb.2: # %backedge 99; CHECK-NEXT: # in Loop: Header=BB2_1 Depth=1 100; CHECK-NEXT: cmpl %edx, (%rdi) 101; CHECK-NEXT: leaq 4(%rdi), %rdi 102; CHECK-NEXT: jne .LBB2_1 103; CHECK-NEXT: # %bb.3: # %failure 104; CHECK-NEXT: .LBB2_4: # %exit 105; CHECK-NEXT: movl $-1, %eax 106; CHECK-NEXT: retq 107entry: 108 %len.plus.1 = add i64 %len, 1 109 %scevgep = getelementptr i32, ptr %p, i64 -1 110 br label %loop 111 112loop: ; preds = %backedge, %entry 113 %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ] 114 %iv.next = add nsw i64 %iv, 1 115 %cond_1 = icmp eq i64 %iv.next, %len.plus.1 116 br i1 %cond_1, label %exit, label %backedge 117 118backedge: ; preds = %loop 119 %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv 120 %loaded = load atomic i32, ptr %scevgep1 unordered, align 4 121 %cond_2 = icmp eq i32 %loaded, %x 122 br i1 %cond_2, label %failure, label %loop 123 124exit: ; preds = %loop 125 ret i32 -1 126 127failure: ; preds = %backedge 128 unreachable 129} 130 131 132; nuw flag, same type width. 133define i32 @test_03(ptr %p, i64 %len, i32 %x) { 134; CHECK-LABEL: test_03: 135; CHECK: # %bb.0: # %entry 136; CHECK-NEXT: addq $-4, %rdi 137; CHECK-NEXT: .p2align 4 138; CHECK-NEXT: .LBB3_1: # %loop 139; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 140; CHECK-NEXT: subq $1, %rsi 141; CHECK-NEXT: jb .LBB3_4 142; CHECK-NEXT: # %bb.2: # %backedge 143; CHECK-NEXT: # in Loop: Header=BB3_1 Depth=1 144; CHECK-NEXT: cmpl %edx, (%rdi) 145; CHECK-NEXT: leaq 4(%rdi), %rdi 146; CHECK-NEXT: jne .LBB3_1 147; CHECK-NEXT: # %bb.3: # %failure 148; CHECK-NEXT: .LBB3_4: # %exit 149; CHECK-NEXT: movl $-1, %eax 150; CHECK-NEXT: retq 151entry: 152 %scevgep = getelementptr i32, ptr %p, i64 -1 153 br label %loop 154 155loop: ; preds = %backedge, %entry 156 %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ] 157 %iv.next = add nuw i64 %iv, 1 158 %cond_1 = icmp eq i64 %iv, %len 159 br i1 %cond_1, label %exit, label %backedge 160 161backedge: ; preds = %loop 162 %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv 163 %loaded = load atomic i32, ptr %scevgep1 unordered, align 4 164 %cond_2 = icmp eq i32 %loaded, %x 165 br i1 %cond_2, label %failure, label %loop 166 167exit: ; preds = %loop 168 ret i32 -1 169 170failure: ; preds = %backedge 171 unreachable 172} 173 174; nuw flag, optimization is possible because memory instruction is dominated by loop-exiting check against iv.next. 175define i32 @test_03_nopoison(ptr %p, i64 %len, i32 %x) { 176; CHECK-LABEL: test_03_nopoison: 177; CHECK: # %bb.0: # %entry 178; CHECK-NEXT: addq $-4, %rdi 179; CHECK-NEXT: .p2align 4 180; CHECK-NEXT: .LBB4_1: # %loop 181; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 182; CHECK-NEXT: subq $1, %rsi 183; CHECK-NEXT: jb .LBB4_4 184; CHECK-NEXT: # %bb.2: # %backedge 185; CHECK-NEXT: # in Loop: Header=BB4_1 Depth=1 186; CHECK-NEXT: cmpl %edx, (%rdi) 187; CHECK-NEXT: leaq 4(%rdi), %rdi 188; CHECK-NEXT: jne .LBB4_1 189; CHECK-NEXT: # %bb.3: # %failure 190; CHECK-NEXT: .LBB4_4: # %exit 191; CHECK-NEXT: movl $-1, %eax 192; CHECK-NEXT: retq 193entry: 194 %len.plus.1 = add i64 %len, 1 195 %scevgep = getelementptr i32, ptr %p, i64 -1 196 br label %loop 197 198loop: ; preds = %backedge, %entry 199 %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ] 200 %iv.next = add nuw i64 %iv, 1 201 %cond_1 = icmp eq i64 %iv.next, %len.plus.1 202 br i1 %cond_1, label %exit, label %backedge 203 204backedge: ; preds = %loop 205 %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv 206 %loaded = load atomic i32, ptr %scevgep1 unordered, align 4 207 %cond_2 = icmp eq i32 %loaded, %x 208 br i1 %cond_2, label %failure, label %loop 209 210exit: ; preds = %loop 211 ret i32 -1 212 213failure: ; preds = %backedge 214 unreachable 215} 216