319 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc < %s -mtriple=aarch64-- -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5%struct.anon = type { ptr, ptr }6 7@ptr_wrapper = common global ptr null, align 88 9define i32 @test_func_i32_two_uses(i32 %in, i32 %bit, i32 %mask) {10; CHECK-SD-LABEL: test_func_i32_two_uses:11; CHECK-SD: // %bb.0: // %entry12; CHECK-SD-NEXT: adrp x8, :got:ptr_wrapper13; CHECK-SD-NEXT: ldr x8, [x8, :got_lo12:ptr_wrapper]14; CHECK-SD-NEXT: ldr x9, [x8]15; CHECK-SD-NEXT: mov w8, wzr16; CHECK-SD-NEXT: b .LBB0_317; CHECK-SD-NEXT: .LBB0_1: // in Loop: Header=BB0_3 Depth=118; CHECK-SD-NEXT: str xzr, [x9, #8]19; CHECK-SD-NEXT: .LBB0_2: // in Loop: Header=BB0_3 Depth=120; CHECK-SD-NEXT: lsl w1, w1, #121; CHECK-SD-NEXT: cbz w1, .LBB0_622; CHECK-SD-NEXT: .LBB0_3: // %do.body23; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=124; CHECK-SD-NEXT: ands w10, w1, w025; CHECK-SD-NEXT: and w11, w2, w026; CHECK-SD-NEXT: cinc w8, w8, ne27; CHECK-SD-NEXT: cmp w10, w1128; CHECK-SD-NEXT: b.eq .LBB0_129; CHECK-SD-NEXT: // %bb.4: // %do.body30; CHECK-SD-NEXT: // in Loop: Header=BB0_3 Depth=131; CHECK-SD-NEXT: cbnz w2, .LBB0_132; CHECK-SD-NEXT: // %bb.5: // %do.body33; CHECK-SD-NEXT: // in Loop: Header=BB0_3 Depth=134; CHECK-SD-NEXT: cbz w10, .LBB0_235; CHECK-SD-NEXT: b .LBB0_136; CHECK-SD-NEXT: .LBB0_6: // %do.end37; CHECK-SD-NEXT: mov w0, w838; CHECK-SD-NEXT: ret39;40; CHECK-GI-LABEL: test_func_i32_two_uses:41; CHECK-GI: // %bb.0: // %entry42; CHECK-GI-NEXT: adrp x8, :got:ptr_wrapper43; CHECK-GI-NEXT: ldr x8, [x8, :got_lo12:ptr_wrapper]44; CHECK-GI-NEXT: ldr x9, [x8]45; CHECK-GI-NEXT: mov w8, wzr46; CHECK-GI-NEXT: b .LBB0_347; CHECK-GI-NEXT: .LBB0_1: // in Loop: Header=BB0_3 Depth=148; CHECK-GI-NEXT: str xzr, [x9, #8]49; CHECK-GI-NEXT: .LBB0_2: // in Loop: Header=BB0_3 Depth=150; CHECK-GI-NEXT: lsl w1, w1, #151; CHECK-GI-NEXT: cbz w1, .LBB0_652; CHECK-GI-NEXT: .LBB0_3: // %do.body53; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=154; CHECK-GI-NEXT: and w10, w1, w055; CHECK-GI-NEXT: tst w1, w056; CHECK-GI-NEXT: and w11, w2, w057; CHECK-GI-NEXT: cinc w8, w8, ne58; CHECK-GI-NEXT: cmp w10, w1159; CHECK-GI-NEXT: b.eq .LBB0_160; CHECK-GI-NEXT: // %bb.4: // %do.body61; CHECK-GI-NEXT: // in Loop: Header=BB0_3 Depth=162; CHECK-GI-NEXT: cbnz w2, .LBB0_163; CHECK-GI-NEXT: // %bb.5: // %do.body64; CHECK-GI-NEXT: // in Loop: Header=BB0_3 Depth=165; CHECK-GI-NEXT: cbz w10, .LBB0_266; CHECK-GI-NEXT: b .LBB0_167; CHECK-GI-NEXT: .LBB0_6: // %do.end68; CHECK-GI-NEXT: mov w0, w869; CHECK-GI-NEXT: ret70entry:71 %0 = load ptr, ptr @ptr_wrapper, align 872 %result = getelementptr inbounds %struct.anon, ptr %0, i64 0, i32 173 %tobool2 = icmp ne i32 %mask, 074 br label %do.body75 76do.body: ; preds = %4, %entry77 %bit.addr.0 = phi i32 [ %bit, %entry ], [ %shl, %4 ]78 %retval1.0 = phi i32 [ 0, %entry ], [ %retval1.1, %4 ]79 %and = and i32 %bit.addr.0, %in80 %tobool = icmp eq i32 %and, 081 %not.tobool = xor i1 %tobool, true82 %inc = zext i1 %not.tobool to i3283 %retval1.1 = add nuw nsw i32 %retval1.0, %inc84 %1 = xor i1 %tobool, true85 %2 = or i1 %tobool2, %186 %dummy = and i32 %mask, %in87 %use_and = icmp eq i32 %and, %dummy88 %dummy_or = or i1 %use_and, %289 br i1 %dummy_or, label %3, label %490 913: ; preds = %do.body92 store ptr null, ptr %result, align 893 br label %494 954: ; preds = %do.body, %396 %shl = shl i32 %bit.addr.0, 197 %tobool6 = icmp eq i32 %shl, 098 br i1 %tobool6, label %do.end, label %do.body99 100do.end: ; preds = %4101 ret i32 %retval1.1102}103 104define i32 @test_func_i64_one_use(i64 %in, i64 %bit, i64 %mask) {105; CHECK-SD-LABEL: test_func_i64_one_use:106; CHECK-SD: // %bb.0: // %entry107; CHECK-SD-NEXT: adrp x8, :got:ptr_wrapper108; CHECK-SD-NEXT: ldr x8, [x8, :got_lo12:ptr_wrapper]109; CHECK-SD-NEXT: ldr x9, [x8]110; CHECK-SD-NEXT: mov w8, wzr111; CHECK-SD-NEXT: b .LBB1_2112; CHECK-SD-NEXT: .LBB1_1: // in Loop: Header=BB1_2 Depth=1113; CHECK-SD-NEXT: lsl x1, x1, #1114; CHECK-SD-NEXT: cbz x1, .LBB1_4115; CHECK-SD-NEXT: .LBB1_2: // %do.body116; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1117; CHECK-SD-NEXT: ands x10, x1, x0118; CHECK-SD-NEXT: orr x10, x2, x10119; CHECK-SD-NEXT: cinc w8, w8, ne120; CHECK-SD-NEXT: cbz x10, .LBB1_1121; CHECK-SD-NEXT: // %bb.3: // in Loop: Header=BB1_2 Depth=1122; CHECK-SD-NEXT: str xzr, [x9, #8]123; CHECK-SD-NEXT: b .LBB1_1124; CHECK-SD-NEXT: .LBB1_4: // %do.end125; CHECK-SD-NEXT: mov w0, w8126; CHECK-SD-NEXT: ret127;128; CHECK-GI-LABEL: test_func_i64_one_use:129; CHECK-GI: // %bb.0: // %entry130; CHECK-GI-NEXT: adrp x8, :got:ptr_wrapper131; CHECK-GI-NEXT: ldr x8, [x8, :got_lo12:ptr_wrapper]132; CHECK-GI-NEXT: ldr x9, [x8]133; CHECK-GI-NEXT: mov w8, wzr134; CHECK-GI-NEXT: b .LBB1_2135; CHECK-GI-NEXT: .LBB1_1: // in Loop: Header=BB1_2 Depth=1136; CHECK-GI-NEXT: lsl x1, x1, #1137; CHECK-GI-NEXT: cbz x1, .LBB1_4138; CHECK-GI-NEXT: .LBB1_2: // %do.body139; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1140; CHECK-GI-NEXT: and x10, x1, x0141; CHECK-GI-NEXT: tst x1, x0142; CHECK-GI-NEXT: orr x10, x2, x10143; CHECK-GI-NEXT: cinc w8, w8, ne144; CHECK-GI-NEXT: cbz x10, .LBB1_1145; CHECK-GI-NEXT: // %bb.3: // in Loop: Header=BB1_2 Depth=1146; CHECK-GI-NEXT: str xzr, [x9, #8]147; CHECK-GI-NEXT: b .LBB1_1148; CHECK-GI-NEXT: .LBB1_4: // %do.end149; CHECK-GI-NEXT: mov w0, w8150; CHECK-GI-NEXT: ret151entry:152 %0 = load ptr, ptr @ptr_wrapper, align 8153 %result = getelementptr inbounds %struct.anon, ptr %0, i64 0, i32 1154 %tobool2 = icmp ne i64 %mask, 0155 br label %do.body156 157do.body: ; preds = %4, %entry158 %bit.addr.0 = phi i64 [ %bit, %entry ], [ %shl, %4 ]159 %retval1.0 = phi i32 [ 0, %entry ], [ %retval1.1, %4 ]160 %and = and i64 %bit.addr.0, %in161 %tobool = icmp eq i64 %and, 0162 %not.tobool = xor i1 %tobool, true163 %inc = zext i1 %not.tobool to i32164 %retval1.1 = add nuw nsw i32 %retval1.0, %inc165 %1 = xor i1 %tobool, true166 %2 = or i1 %tobool2, %1167 br i1 %2, label %3, label %4168 1693: ; preds = %do.body170 store ptr null, ptr %result, align 8171 br label %4172 1734: ; preds = %do.body, %3174 %shl = shl i64 %bit.addr.0, 1175 %tobool6 = icmp eq i64 %shl, 0176 br i1 %tobool6, label %do.end, label %do.body177 178do.end: ; preds = %4179 ret i32 %retval1.1180}181 182define i64 @test_and1(i64 %x, i64 %y) {183; CHECK-SD-LABEL: test_and1:184; CHECK-SD: // %bb.0:185; CHECK-SD-NEXT: ands x8, x0, #0x3186; CHECK-SD-NEXT: csel x0, x8, x1, eq187; CHECK-SD-NEXT: ret188;189; CHECK-GI-LABEL: test_and1:190; CHECK-GI: // %bb.0:191; CHECK-GI-NEXT: and x8, x0, #0x3192; CHECK-GI-NEXT: tst x0, #0x3193; CHECK-GI-NEXT: csel x0, x8, x1, eq194; CHECK-GI-NEXT: ret195 %a = and i64 %x, 3196 %c = icmp eq i64 %a, 0197 %s = select i1 %c, i64 %a, i64 %y198 ret i64 %s199}200 201define i64 @test_and2(i64 %x, i64 %y) {202; CHECK-LABEL: test_and2:203; CHECK: // %bb.0:204; CHECK-NEXT: tst x0, #0x3205; CHECK-NEXT: csel x0, x0, x1, eq206; CHECK-NEXT: ret207 %a = and i64 %x, 3208 %c = icmp eq i64 %a, 0209 %s = select i1 %c, i64 %x, i64 %y210 ret i64 %s211}212 213define i64 @test_and3(i64 %x, i64 %y) {214; CHECK-SD-LABEL: test_and3:215; CHECK-SD: // %bb.0:216; CHECK-SD-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill217; CHECK-SD-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill218; CHECK-SD-NEXT: .cfi_def_cfa_offset 32219; CHECK-SD-NEXT: .cfi_offset w19, -8220; CHECK-SD-NEXT: .cfi_offset w20, -16221; CHECK-SD-NEXT: .cfi_offset w30, -32222; CHECK-SD-NEXT: mov x20, x0223; CHECK-SD-NEXT: mov x0, xzr224; CHECK-SD-NEXT: mov x19, x1225; CHECK-SD-NEXT: bl callee226; CHECK-SD-NEXT: ands x8, x20, #0x3227; CHECK-SD-NEXT: csel x0, x8, x19, eq228; CHECK-SD-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload229; CHECK-SD-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload230; CHECK-SD-NEXT: ret231;232; CHECK-GI-LABEL: test_and3:233; CHECK-GI: // %bb.0:234; CHECK-GI-NEXT: stp x30, x21, [sp, #-32]! // 16-byte Folded Spill235; CHECK-GI-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill236; CHECK-GI-NEXT: .cfi_def_cfa_offset 32237; CHECK-GI-NEXT: .cfi_offset w19, -8238; CHECK-GI-NEXT: .cfi_offset w20, -16239; CHECK-GI-NEXT: .cfi_offset w21, -24240; CHECK-GI-NEXT: .cfi_offset w30, -32241; CHECK-GI-NEXT: mov x19, x0242; CHECK-GI-NEXT: and x21, x0, #0x3243; CHECK-GI-NEXT: mov x0, xzr244; CHECK-GI-NEXT: mov x20, x1245; CHECK-GI-NEXT: bl callee246; CHECK-GI-NEXT: tst x19, #0x3247; CHECK-GI-NEXT: csel x0, x21, x20, eq248; CHECK-GI-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload249; CHECK-GI-NEXT: ldp x30, x21, [sp], #32 // 16-byte Folded Reload250; CHECK-GI-NEXT: ret251 %a = and i64 %x, 3252 %b = call i64 @callee(i64 0)253 %c = icmp eq i64 %a, 0254 %s = select i1 %c, i64 %a, i64 %y255 ret i64 %s256}257 258define i64 @test_and_4(i64 %x, i64 %y) {259; CHECK-SD-LABEL: test_and_4:260; CHECK-SD: // %bb.0:261; CHECK-SD-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill262; CHECK-SD-NEXT: .cfi_def_cfa_offset 16263; CHECK-SD-NEXT: .cfi_offset w19, -8264; CHECK-SD-NEXT: .cfi_offset w30, -16265; CHECK-SD-NEXT: mov x19, x0266; CHECK-SD-NEXT: ands x0, x0, #0x3267; CHECK-SD-NEXT: bl callee268; CHECK-SD-NEXT: ands x8, x19, #0x3269; CHECK-SD-NEXT: csel x0, x8, x0, eq270; CHECK-SD-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload271; CHECK-SD-NEXT: ret272;273; CHECK-GI-LABEL: test_and_4:274; CHECK-GI: // %bb.0:275; CHECK-GI-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill276; CHECK-GI-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill277; CHECK-GI-NEXT: .cfi_def_cfa_offset 32278; CHECK-GI-NEXT: .cfi_offset w19, -8279; CHECK-GI-NEXT: .cfi_offset w20, -16280; CHECK-GI-NEXT: .cfi_offset w30, -32281; CHECK-GI-NEXT: mov x19, x0282; CHECK-GI-NEXT: and x20, x0, #0x3283; CHECK-GI-NEXT: and x0, x0, #0x3284; CHECK-GI-NEXT: bl callee285; CHECK-GI-NEXT: tst x19, #0x3286; CHECK-GI-NEXT: csel x0, x20, x0, eq287; CHECK-GI-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload288; CHECK-GI-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload289; CHECK-GI-NEXT: ret290 %a = and i64 %x, 3291 %b = call i64 @callee(i64 %a)292 %c = icmp eq i64 %a, 0293 %s = select i1 %c, i64 %a, i64 %b294 ret i64 %s295}296 297define i64 @test_add(i64 %x, i64 %y) {298; CHECK-LABEL: test_add:299; CHECK: // %bb.0:300; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill301; CHECK-NEXT: .cfi_def_cfa_offset 16302; CHECK-NEXT: .cfi_offset w19, -8303; CHECK-NEXT: .cfi_offset w30, -16304; CHECK-NEXT: add x19, x0, #3305; CHECK-NEXT: mov x0, xzr306; CHECK-NEXT: bl callee307; CHECK-NEXT: cmp x19, #0308; CHECK-NEXT: csel x0, x19, x0, eq309; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload310; CHECK-NEXT: ret311 %a = add i64 %x, 3312 %b = call i64 @callee(i64 0)313 %c = icmp eq i64 %a, 0314 %s = select i1 %c, i64 %a, i64 %b315 ret i64 %s316}317 318declare i64 @callee(i64)319