1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s 3 4%struct.anon = type { ptr, ptr } 5 6@ptr_wrapper = common global ptr null, align 8 7 8define i32 @test_func_i32_two_uses(i32 %in, i32 %bit, i32 %mask) { 9; CHECK-LABEL: test_func_i32_two_uses: 10; CHECK: // %bb.0: // %entry 11; CHECK-NEXT: adrp x8, :got:ptr_wrapper 12; CHECK-NEXT: ldr x8, [x8, :got_lo12:ptr_wrapper] 13; CHECK-NEXT: ldr x9, [x8] 14; CHECK-NEXT: mov w8, wzr 15; CHECK-NEXT: b .LBB0_3 16; CHECK-NEXT: .LBB0_1: // in Loop: Header=BB0_3 Depth=1 17; CHECK-NEXT: str xzr, [x9, #8] 18; CHECK-NEXT: .LBB0_2: // in Loop: Header=BB0_3 Depth=1 19; CHECK-NEXT: lsl w1, w1, #1 20; CHECK-NEXT: cbz w1, .LBB0_6 21; CHECK-NEXT: .LBB0_3: // %do.body 22; CHECK-NEXT: // =>This Inner Loop Header: Depth=1 23; CHECK-NEXT: ands w10, w1, w0 24; CHECK-NEXT: and w11, w2, w0 25; CHECK-NEXT: cinc w8, w8, ne 26; CHECK-NEXT: cmp w10, w11 27; CHECK-NEXT: b.eq .LBB0_1 28; CHECK-NEXT: // %bb.4: // %do.body 29; CHECK-NEXT: // in Loop: Header=BB0_3 Depth=1 30; CHECK-NEXT: cbnz w2, .LBB0_1 31; CHECK-NEXT: // %bb.5: // %do.body 32; CHECK-NEXT: // in Loop: Header=BB0_3 Depth=1 33; CHECK-NEXT: cbz w10, .LBB0_2 34; CHECK-NEXT: b .LBB0_1 35; CHECK-NEXT: .LBB0_6: // %do.end 36; CHECK-NEXT: mov w0, w8 37; CHECK-NEXT: ret 38entry: 39 %0 = load ptr, ptr @ptr_wrapper, align 8 40 %result = getelementptr inbounds %struct.anon, ptr %0, i64 0, i32 1 41 %tobool2 = icmp ne i32 %mask, 0 42 br label %do.body 43 44do.body: ; preds = %4, %entry 45 %bit.addr.0 = phi i32 [ %bit, %entry ], [ %shl, %4 ] 46 %retval1.0 = phi i32 [ 0, %entry ], [ %retval1.1, %4 ] 47 %and = and i32 %bit.addr.0, %in 48 %tobool = icmp eq i32 %and, 0 49 %not.tobool = xor i1 %tobool, true 50 %inc = zext i1 %not.tobool to i32 51 %retval1.1 = add nuw nsw i32 %retval1.0, %inc 52 %1 = xor i1 %tobool, true 53 %2 = or i1 %tobool2, %1 54 %dummy = and i32 %mask, %in 55 %use_and = icmp eq i32 %and, %dummy 56 %dummy_or = or i1 %use_and, %2 57 br i1 %dummy_or, label %3, label %4 58 593: ; preds = %do.body 60 store ptr null, ptr %result, align 8 61 br label %4 62 634: ; preds = %do.body, %3 64 %shl = shl i32 %bit.addr.0, 1 65 %tobool6 = icmp eq i32 %shl, 0 66 br i1 %tobool6, label %do.end, label %do.body 67 68do.end: ; preds = %4 69 ret i32 %retval1.1 70} 71 72define i32 @test_func_i64_one_use(i64 %in, i64 %bit, i64 %mask) { 73; CHECK-LABEL: test_func_i64_one_use: 74; CHECK: // %bb.0: // %entry 75; CHECK-NEXT: adrp x8, :got:ptr_wrapper 76; CHECK-NEXT: ldr x8, [x8, :got_lo12:ptr_wrapper] 77; CHECK-NEXT: ldr x9, [x8] 78; CHECK-NEXT: mov w8, wzr 79; CHECK-NEXT: b .LBB1_2 80; CHECK-NEXT: .LBB1_1: // in Loop: Header=BB1_2 Depth=1 81; CHECK-NEXT: lsl x1, x1, #1 82; CHECK-NEXT: cbz x1, .LBB1_4 83; CHECK-NEXT: .LBB1_2: // %do.body 84; CHECK-NEXT: // =>This Inner Loop Header: Depth=1 85; CHECK-NEXT: ands x10, x1, x0 86; CHECK-NEXT: orr x10, x2, x10 87; CHECK-NEXT: cinc w8, w8, ne 88; CHECK-NEXT: cbz x10, .LBB1_1 89; CHECK-NEXT: // %bb.3: // in Loop: Header=BB1_2 Depth=1 90; CHECK-NEXT: str xzr, [x9, #8] 91; CHECK-NEXT: b .LBB1_1 92; CHECK-NEXT: .LBB1_4: // %do.end 93; CHECK-NEXT: mov w0, w8 94; CHECK-NEXT: ret 95entry: 96 %0 = load ptr, ptr @ptr_wrapper, align 8 97 %result = getelementptr inbounds %struct.anon, ptr %0, i64 0, i32 1 98 %tobool2 = icmp ne i64 %mask, 0 99 br label %do.body 100 101do.body: ; preds = %4, %entry 102 %bit.addr.0 = phi i64 [ %bit, %entry ], [ %shl, %4 ] 103 %retval1.0 = phi i32 [ 0, %entry ], [ %retval1.1, %4 ] 104 %and = and i64 %bit.addr.0, %in 105 %tobool = icmp eq i64 %and, 0 106 %not.tobool = xor i1 %tobool, true 107 %inc = zext i1 %not.tobool to i32 108 %retval1.1 = add nuw nsw i32 %retval1.0, %inc 109 %1 = xor i1 %tobool, true 110 %2 = or i1 %tobool2, %1 111 br i1 %2, label %3, label %4 112 1133: ; preds = %do.body 114 store ptr null, ptr %result, align 8 115 br label %4 116 1174: ; preds = %do.body, %3 118 %shl = shl i64 %bit.addr.0, 1 119 %tobool6 = icmp eq i64 %shl, 0 120 br i1 %tobool6, label %do.end, label %do.body 121 122do.end: ; preds = %4 123 ret i32 %retval1.1 124} 125 126define i64 @test_and1(i64 %x, i64 %y) { 127; CHECK-LABEL: test_and1: 128; CHECK: // %bb.0: 129; CHECK-NEXT: ands x8, x0, #0x3 130; CHECK-NEXT: csel x0, x8, x1, eq 131; CHECK-NEXT: ret 132 %a = and i64 %x, 3 133 %c = icmp eq i64 %a, 0 134 %s = select i1 %c, i64 %a, i64 %y 135 ret i64 %s 136} 137 138define i64 @test_and2(i64 %x, i64 %y) { 139; CHECK-LABEL: test_and2: 140; CHECK: // %bb.0: 141; CHECK-NEXT: tst x0, #0x3 142; CHECK-NEXT: csel x0, x0, x1, eq 143; CHECK-NEXT: ret 144 %a = and i64 %x, 3 145 %c = icmp eq i64 %a, 0 146 %s = select i1 %c, i64 %x, i64 %y 147 ret i64 %s 148} 149 150define i64 @test_and3(i64 %x, i64 %y) { 151; CHECK-LABEL: test_and3: 152; CHECK: // %bb.0: 153; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill 154; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill 155; CHECK-NEXT: .cfi_def_cfa_offset 32 156; CHECK-NEXT: .cfi_offset w19, -8 157; CHECK-NEXT: .cfi_offset w20, -16 158; CHECK-NEXT: .cfi_offset w30, -32 159; CHECK-NEXT: mov x20, x0 160; CHECK-NEXT: mov x0, xzr 161; CHECK-NEXT: mov x19, x1 162; CHECK-NEXT: bl callee 163; CHECK-NEXT: ands x8, x20, #0x3 164; CHECK-NEXT: csel x0, x8, x19, eq 165; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload 166; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload 167; CHECK-NEXT: ret 168 %a = and i64 %x, 3 169 %b = call i64 @callee(i64 0) 170 %c = icmp eq i64 %a, 0 171 %s = select i1 %c, i64 %a, i64 %y 172 ret i64 %s 173} 174 175define i64 @test_and_4(i64 %x, i64 %y) { 176; CHECK-LABEL: test_and_4: 177; CHECK: // %bb.0: 178; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 179; CHECK-NEXT: .cfi_def_cfa_offset 16 180; CHECK-NEXT: .cfi_offset w19, -8 181; CHECK-NEXT: .cfi_offset w30, -16 182; CHECK-NEXT: mov x19, x0 183; CHECK-NEXT: ands x0, x0, #0x3 184; CHECK-NEXT: bl callee 185; CHECK-NEXT: ands x8, x19, #0x3 186; CHECK-NEXT: csel x0, x8, x0, eq 187; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 188; CHECK-NEXT: ret 189 %a = and i64 %x, 3 190 %b = call i64 @callee(i64 %a) 191 %c = icmp eq i64 %a, 0 192 %s = select i1 %c, i64 %a, i64 %b 193 ret i64 %s 194} 195 196define i64 @test_add(i64 %x, i64 %y) { 197; CHECK-LABEL: test_add: 198; CHECK: // %bb.0: 199; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 200; CHECK-NEXT: .cfi_def_cfa_offset 16 201; CHECK-NEXT: .cfi_offset w19, -8 202; CHECK-NEXT: .cfi_offset w30, -16 203; CHECK-NEXT: add x19, x0, #3 204; CHECK-NEXT: mov x0, xzr 205; CHECK-NEXT: bl callee 206; CHECK-NEXT: cmp x19, #0 207; CHECK-NEXT: csel x0, x19, x0, eq 208; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 209; CHECK-NEXT: ret 210 %a = add i64 %x, 3 211 %b = call i64 @callee(i64 0) 212 %c = icmp eq i64 %a, 0 213 %s = select i1 %c, i64 %a, i64 %b 214 ret i64 %s 215} 216 217declare i64 @callee(i64) 218