991 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-none-elf < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc -mtriple=aarch64-none-elf -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5; Add pure 12-bit immediates:6define i32 @add_small_i32(i32 %val32) {7; CHECK-LABEL: add_small_i32:8; CHECK: // %bb.0:9; CHECK-NEXT: add w0, w0, #409510; CHECK-NEXT: ret11 %newval32 = add i32 %val32, 409512 ret i32 %newval3213}14 15define i64 @add_small_i64(i64 %val64) {16; CHECK-LABEL: add_small_i64:17; CHECK: // %bb.0:18; CHECK-NEXT: add x0, x0, #5219; CHECK-NEXT: ret20 %newval64 = add i64 %val64, 5221 ret i64 %newval6422}23 24define void @add_small_imm(ptr %p, ptr %q, i32 %b, ptr %addr) {25; CHECK-LABEL: add_small_imm:26; CHECK: // %bb.0: // %entry27; CHECK-NEXT: ldrb w8, [x0]28; CHECK-NEXT: add w9, w8, w229; CHECK-NEXT: add x8, x8, #1230; CHECK-NEXT: str w9, [x3]31; CHECK-NEXT: str x8, [x1]32; CHECK-NEXT: ret33entry:34 %t = load i8, ptr %p35 %promoted = zext i8 %t to i6436 %zextt = zext i8 %t to i3237 %add = add nuw i32 %zextt, %b38 %add2 = add nuw i64 %promoted, 1239 store i32 %add, ptr %addr40 store i64 %add2, ptr %q41 ret void42}43 44; Add 12-bit immediates, shifted left by 12 bits45define i32 @add_med_i32(i32 %val32) {46; CHECK-LABEL: add_med_i32:47; CHECK: // %bb.0:48; CHECK-NEXT: add w0, w0, #3567, lsl #12 // =1461043249; CHECK-NEXT: ret50 %newval32 = add i32 %val32, 14610432 ; =0xdef00051 ret i32 %newval3252}53 54define i64 @add_med_i64(i64 %val64) {55; CHECK-LABEL: add_med_i64:56; CHECK: // %bb.0:57; CHECK-NEXT: add x0, x0, #4095, lsl #12 // =1677312058; CHECK-NEXT: ret59 %newval64 = add i64 %val64, 16773120 ; =0xfff00060 ret i64 %newval6461}62 63; Subtract 12-bit immediates64define i32 @sub_small_i32(i32 %val32) {65; CHECK-LABEL: sub_small_i32:66; CHECK: // %bb.0:67; CHECK-NEXT: sub w0, w0, #409568; CHECK-NEXT: ret69 %newval32 = sub i32 %val32, 409570 ret i32 %newval3271}72 73define i64 @sub_small_i64(i64 %val64) {74; CHECK-LABEL: sub_small_i64:75; CHECK: // %bb.0:76; CHECK-NEXT: sub x0, x0, #5277; CHECK-NEXT: ret78 %newval64 = sub i64 %val64, 5279 ret i64 %newval6480}81 82; Subtract 12-bit immediates, shifted left by 12 bits83define i32 @sub_med_i32(i32 %val32) {84; CHECK-LABEL: sub_med_i32:85; CHECK: // %bb.0:86; CHECK-NEXT: sub w0, w0, #3567, lsl #12 // =1461043287; CHECK-NEXT: ret88 %newval32 = sub i32 %val32, 14610432 ; =0xdef00089 ret i32 %newval3290}91 92define i64 @sub_med_i64(i64 %val64) {93; CHECK-LABEL: sub_med_i64:94; CHECK: // %bb.0:95; CHECK-NEXT: sub x0, x0, #4095, lsl #12 // =1677312096; CHECK-NEXT: ret97 %newval64 = sub i64 %val64, 16773120 ; =0xfff00098 ret i64 %newval6499}100 101define i64 @add_two_parts_imm_i64(i64 %a) {102; CHECK-LABEL: add_two_parts_imm_i64:103; CHECK: // %bb.0:104; CHECK-NEXT: add x8, x0, #2730, lsl #12 // =11182080105; CHECK-NEXT: add x0, x8, #1365106; CHECK-NEXT: ret107 %b = add i64 %a, 11183445108 ret i64 %b109}110 111define i32 @add_two_parts_imm_i32(i32 %a) {112; CHECK-LABEL: add_two_parts_imm_i32:113; CHECK: // %bb.0:114; CHECK-NEXT: add w8, w0, #2730, lsl #12 // =11182080115; CHECK-NEXT: add w0, w8, #1365116; CHECK-NEXT: ret117 %b = add i32 %a, 11183445118 ret i32 %b119}120 121define i64 @add_two_parts_imm_i64_neg(i64 %a) {122; CHECK-LABEL: add_two_parts_imm_i64_neg:123; CHECK: // %bb.0:124; CHECK-NEXT: sub x8, x0, #2730, lsl #12 // =11182080125; CHECK-NEXT: sub x0, x8, #1365126; CHECK-NEXT: ret127 %b = add i64 %a, -11183445128 ret i64 %b129}130 131define i32 @add_two_parts_imm_i32_neg(i32 %a) {132; CHECK-LABEL: add_two_parts_imm_i32_neg:133; CHECK: // %bb.0:134; CHECK-NEXT: sub w8, w0, #2730, lsl #12 // =11182080135; CHECK-NEXT: sub w0, w8, #1365136; CHECK-NEXT: ret137 %b = add i32 %a, -11183445138 ret i32 %b139}140 141define i64 @sub_two_parts_imm_i64(i64 %a) {142; CHECK-LABEL: sub_two_parts_imm_i64:143; CHECK: // %bb.0:144; CHECK-NEXT: sub x8, x0, #2730, lsl #12 // =11182080145; CHECK-NEXT: sub x0, x8, #1365146; CHECK-NEXT: ret147 %b = sub i64 %a, 11183445148 ret i64 %b149}150 151define i32 @sub_two_parts_imm_i32(i32 %a) {152; CHECK-LABEL: sub_two_parts_imm_i32:153; CHECK: // %bb.0:154; CHECK-NEXT: sub w8, w0, #2730, lsl #12 // =11182080155; CHECK-NEXT: sub w0, w8, #1365156; CHECK-NEXT: ret157 %b = sub i32 %a, 11183445158 ret i32 %b159}160 161define i64 @sub_two_parts_imm_i64_neg(i64 %a) {162; CHECK-LABEL: sub_two_parts_imm_i64_neg:163; CHECK: // %bb.0:164; CHECK-NEXT: add x8, x0, #2730, lsl #12 // =11182080165; CHECK-NEXT: add x0, x8, #1365166; CHECK-NEXT: ret167 %b = sub i64 %a, -11183445168 ret i64 %b169}170 171define i32 @sub_two_parts_imm_i32_neg(i32 %a) {172; CHECK-LABEL: sub_two_parts_imm_i32_neg:173; CHECK: // %bb.0:174; CHECK-NEXT: add w8, w0, #2730, lsl #12 // =11182080175; CHECK-NEXT: add w0, w8, #1365176; CHECK-NEXT: ret177 %b = sub i32 %a, -11183445178 ret i32 %b179}180 181define i32 @add_27962026(i32 %a) {182; CHECK-LABEL: add_27962026:183; CHECK: // %bb.0:184; CHECK-NEXT: mov w8, #43690 // =0xaaaa185; CHECK-NEXT: movk w8, #426, lsl #16186; CHECK-NEXT: add w0, w0, w8187; CHECK-NEXT: ret188 %b = add i32 %a, 27962026189 ret i32 %b190}191 192define i32 @add_65534(i32 %a) {193; CHECK-LABEL: add_65534:194; CHECK: // %bb.0:195; CHECK-NEXT: mov w8, #65534 // =0xfffe196; CHECK-NEXT: add w0, w0, w8197; CHECK-NEXT: ret198 %b = add i32 %a, 65534199 ret i32 %b200}201 202declare i32 @foox(i32)203 204define void @add_in_loop(i32 %0) {205; CHECK-LABEL: add_in_loop:206; CHECK: // %bb.0:207; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill208; CHECK-NEXT: .cfi_def_cfa_offset 16209; CHECK-NEXT: .cfi_offset w19, -8210; CHECK-NEXT: .cfi_offset w30, -16211; CHECK-NEXT: mov w19, #43690 // =0xaaaa212; CHECK-NEXT: movk w19, #170, lsl #16213; CHECK-NEXT: .LBB19_1: // =>This Inner Loop Header: Depth=1214; CHECK-NEXT: add w0, w0, w19215; CHECK-NEXT: bl foox216; CHECK-NEXT: b .LBB19_1217 br label %22182:219 %3 = phi i32 [ %0, %1 ], [ %5, %2 ]220 %4 = add nsw i32 %3, 11184810221 %5 = tail call i32 @foox(i32 %4) #2222 br label %2223}224 225define void @testing(ptr %var_i32, ptr %var2_i32) {226; CHECK-SD-LABEL: testing:227; CHECK-SD: // %bb.0:228; CHECK-SD-NEXT: ldr w8, [x0]229; CHECK-SD-NEXT: cmp w8, #4095230; CHECK-SD-NEXT: b.ne .LBB20_6231; CHECK-SD-NEXT: // %bb.1: // %test2232; CHECK-SD-NEXT: ldr w9, [x1]233; CHECK-SD-NEXT: add w10, w8, #1234; CHECK-SD-NEXT: str w10, [x0]235; CHECK-SD-NEXT: cmp w9, #3567, lsl #12 // =14610432236; CHECK-SD-NEXT: b.lo .LBB20_6237; CHECK-SD-NEXT: // %bb.2: // %test3238; CHECK-SD-NEXT: add w10, w8, #2239; CHECK-SD-NEXT: cmp w8, #123240; CHECK-SD-NEXT: str w10, [x0]241; CHECK-SD-NEXT: b.lt .LBB20_6242; CHECK-SD-NEXT: // %bb.3: // %test4243; CHECK-SD-NEXT: add w10, w8, #3244; CHECK-SD-NEXT: cmp w9, #321245; CHECK-SD-NEXT: str w10, [x0]246; CHECK-SD-NEXT: b.gt .LBB20_6247; CHECK-SD-NEXT: // %bb.4: // %test5248; CHECK-SD-NEXT: add w10, w8, #4249; CHECK-SD-NEXT: cmn w9, #443250; CHECK-SD-NEXT: str w10, [x0]251; CHECK-SD-NEXT: b.ge .LBB20_6252; CHECK-SD-NEXT: // %bb.5: // %test6253; CHECK-SD-NEXT: add w8, w8, #5254; CHECK-SD-NEXT: str w8, [x0]255; CHECK-SD-NEXT: .LBB20_6: // %common.ret256; CHECK-SD-NEXT: ret257;258; CHECK-GI-LABEL: testing:259; CHECK-GI: // %bb.0:260; CHECK-GI-NEXT: ldr w8, [x0]261; CHECK-GI-NEXT: cmp w8, #4095262; CHECK-GI-NEXT: b.ne .LBB20_6263; CHECK-GI-NEXT: // %bb.1: // %test2264; CHECK-GI-NEXT: ldr w9, [x1]265; CHECK-GI-NEXT: add w10, w8, #1266; CHECK-GI-NEXT: str w10, [x0]267; CHECK-GI-NEXT: cmp w9, #3567, lsl #12 // =14610432268; CHECK-GI-NEXT: b.lo .LBB20_6269; CHECK-GI-NEXT: // %bb.2: // %test3270; CHECK-GI-NEXT: add w10, w8, #2271; CHECK-GI-NEXT: cmp w8, #123272; CHECK-GI-NEXT: str w10, [x0]273; CHECK-GI-NEXT: b.lt .LBB20_6274; CHECK-GI-NEXT: // %bb.3: // %test4275; CHECK-GI-NEXT: add w10, w8, #3276; CHECK-GI-NEXT: cmp w9, #321277; CHECK-GI-NEXT: str w10, [x0]278; CHECK-GI-NEXT: b.gt .LBB20_6279; CHECK-GI-NEXT: // %bb.4: // %test5280; CHECK-GI-NEXT: add w10, w8, #4281; CHECK-GI-NEXT: cmn w9, #444282; CHECK-GI-NEXT: str w10, [x0]283; CHECK-GI-NEXT: b.gt .LBB20_6284; CHECK-GI-NEXT: // %bb.5: // %test6285; CHECK-GI-NEXT: add w8, w8, #5286; CHECK-GI-NEXT: str w8, [x0]287; CHECK-GI-NEXT: .LBB20_6: // %common.ret288; CHECK-GI-NEXT: ret289 %val = load i32, ptr %var_i32290 %val2 = load i32, ptr %var2_i32291 292 %cmp_pos_small = icmp ne i32 %val, 4095293 br i1 %cmp_pos_small, label %ret, label %test2294 295test2:296 %newval2 = add i32 %val, 1297 store i32 %newval2, ptr %var_i32298 %cmp_pos_big = icmp ult i32 %val2, 14610432299 br i1 %cmp_pos_big, label %ret, label %test3300 301test3:302 %newval3 = add i32 %val, 2303 store i32 %newval3, ptr %var_i32304 %cmp_pos_slt = icmp slt i32 %val, 123305 br i1 %cmp_pos_slt, label %ret, label %test4306 307test4:308 %newval4 = add i32 %val, 3309 store i32 %newval4, ptr %var_i32310 %cmp_pos_sgt = icmp sgt i32 %val2, 321311 br i1 %cmp_pos_sgt, label %ret, label %test5312 313test5:314 %newval5 = add i32 %val, 4315 store i32 %newval5, ptr %var_i32316 %cmp_neg_uge = icmp sgt i32 %val2, -444317 br i1 %cmp_neg_uge, label %ret, label %test6318 319test6:320 %newval6 = add i32 %val, 5321 store i32 %newval6, ptr %var_i32322 ret void323 324ret:325 ret void326}327 328declare {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)329 330define i1 @sadd_add(i32 %a, i32 %b, ptr %p) {331; CHECK-LABEL: sadd_add:332; CHECK: // %bb.0:333; CHECK-NEXT: mvn w8, w0334; CHECK-NEXT: adds w8, w8, w1335; CHECK-NEXT: cset w0, vs336; CHECK-NEXT: add w8, w8, #1337; CHECK-NEXT: str w8, [x2]338; CHECK-NEXT: ret339 %nota = xor i32 %a, -1340 %a0 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %nota, i32 %b)341 %e0 = extractvalue {i32, i1} %a0, 0342 %e1 = extractvalue {i32, i1} %a0, 1343 %res = add i32 %e0, 1344 store i32 %res, ptr %p345 ret i1 %e1346}347 348declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)349 350define i1 @uadd_add(i8 %a, i8 %b, ptr %p) {351; CHECK-SD-LABEL: uadd_add:352; CHECK-SD: // %bb.0:353; CHECK-SD-NEXT: mov w8, #255 // =0xff354; CHECK-SD-NEXT: bic w8, w8, w0355; CHECK-SD-NEXT: add w8, w8, w1, uxtb356; CHECK-SD-NEXT: lsr w0, w8, #8357; CHECK-SD-NEXT: add w8, w8, #1358; CHECK-SD-NEXT: strb w8, [x2]359; CHECK-SD-NEXT: ret360;361; CHECK-GI-LABEL: uadd_add:362; CHECK-GI: // %bb.0:363; CHECK-GI-NEXT: mvn w8, w0364; CHECK-GI-NEXT: and w9, w1, #0xff365; CHECK-GI-NEXT: add w8, w9, w8, uxtb366; CHECK-GI-NEXT: cmp w8, w8, uxtb367; CHECK-GI-NEXT: add w8, w8, #1368; CHECK-GI-NEXT: cset w0, ne369; CHECK-GI-NEXT: strb w8, [x2]370; CHECK-GI-NEXT: ret371 %nota = xor i8 %a, -1372 %a0 = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %nota, i8 %b)373 %e0 = extractvalue {i8, i1} %a0, 0374 %e1 = extractvalue {i8, i1} %a0, 1375 %res = add i8 %e0, 1376 store i8 %res, ptr %p377 ret i1 %e1378}379 380; This is a unique edge case that will generate the following MIR381; MOVi32imm -1000000382; SUBREG_TO_REG 0, killed %1, %subreg.sub_32383; When using a 64-bit unsigned for the "-1000000" immediate, the code384; must make sure to zero out the top 32 bits since SUBREG_TO_REG is385; zero extending the value386define i64 @addl_0x80000000(i64 %a) {387; CHECK-LABEL: addl_0x80000000:388; CHECK: // %bb.0:389; CHECK-NEXT: mov w8, #48576 // =0xbdc0390; CHECK-NEXT: movk w8, #65520, lsl #16391; CHECK-NEXT: add x0, x0, x8392; CHECK-NEXT: ret393 %b = add i64 %a, 4293967296394 ret i64 %b395}396 397; ADDS and SUBS Optimizations398; Checks with all types first, then checks that only EQ and NE optimize399define i1 @eq_i(i32 %0) {400; CHECK-LABEL: eq_i:401; CHECK: // %bb.0:402; CHECK-NEXT: sub w8, w0, #273, lsl #12 // =1118208403; CHECK-NEXT: cmp w8, #273404; CHECK-NEXT: cset w0, eq405; CHECK-NEXT: ret406 %2 = icmp eq i32 %0, 1118481407 ret i1 %2408}409 410define i1 @eq_l(i64 %0) {411; CHECK-LABEL: eq_l:412; CHECK: // %bb.0:413; CHECK-NEXT: sub x8, x0, #273, lsl #12 // =1118208414; CHECK-NEXT: cmp x8, #273415; CHECK-NEXT: cset w0, eq416; CHECK-NEXT: ret417 %2 = icmp eq i64 %0, 1118481418 ret i1 %2419}420 421define i1 @ne_i(i32 %0) {422; CHECK-LABEL: ne_i:423; CHECK: // %bb.0:424; CHECK-NEXT: sub w8, w0, #273, lsl #12 // =1118208425; CHECK-NEXT: cmp w8, #273426; CHECK-NEXT: cset w0, ne427; CHECK-NEXT: ret428 %2 = icmp ne i32 %0, 1118481429 ret i1 %2430}431 432define i1 @ne_l(i64 %0) {433; CHECK-LABEL: ne_l:434; CHECK: // %bb.0:435; CHECK-NEXT: sub x8, x0, #273, lsl #12 // =1118208436; CHECK-NEXT: cmp x8, #273437; CHECK-NEXT: cset w0, ne438; CHECK-NEXT: ret439 %2 = icmp ne i64 %0, 1118481440 ret i1 %2441}442 443define i1 @eq_in(i32 %0) {444; CHECK-LABEL: eq_in:445; CHECK: // %bb.0:446; CHECK-NEXT: add w8, w0, #273, lsl #12 // =1118208447; CHECK-NEXT: cmn w8, #273448; CHECK-NEXT: cset w0, eq449; CHECK-NEXT: ret450 %2 = icmp eq i32 %0, -1118481451 ret i1 %2452}453 454define i1 @eq_ln(i64 %0) {455; CHECK-LABEL: eq_ln:456; CHECK: // %bb.0:457; CHECK-NEXT: add x8, x0, #273, lsl #12 // =1118208458; CHECK-NEXT: cmn x8, #273459; CHECK-NEXT: cset w0, eq460; CHECK-NEXT: ret461 %2 = icmp eq i64 %0, -1118481462 ret i1 %2463}464 465define i1 @ne_in(i32 %0) {466; CHECK-LABEL: ne_in:467; CHECK: // %bb.0:468; CHECK-NEXT: add w8, w0, #273, lsl #12 // =1118208469; CHECK-NEXT: cmn w8, #273470; CHECK-NEXT: cset w0, ne471; CHECK-NEXT: ret472 %2 = icmp ne i32 %0, -1118481473 ret i1 %2474}475 476define i1 @ne_ln(i64 %0) {477; CHECK-LABEL: ne_ln:478; CHECK: // %bb.0:479; CHECK-NEXT: add x8, x0, #273, lsl #12 // =1118208480; CHECK-NEXT: cmn x8, #273481; CHECK-NEXT: cset w0, ne482; CHECK-NEXT: ret483 %2 = icmp ne i64 %0, -1118481484 ret i1 %2485}486 487define i1 @reject_eq(i32 %0) {488; CHECK-LABEL: reject_eq:489; CHECK: // %bb.0:490; CHECK-NEXT: mov w8, #51712 // =0xca00491; CHECK-NEXT: movk w8, #15258, lsl #16492; CHECK-NEXT: cmp w0, w8493; CHECK-NEXT: cset w0, eq494; CHECK-NEXT: ret495 %2 = icmp eq i32 %0, 1000000000496 ret i1 %2497}498 499define i1 @reject_non_eqne_csinc(i32 %0) {500; CHECK-LABEL: reject_non_eqne_csinc:501; CHECK: // %bb.0:502; CHECK-NEXT: mov w8, #4369 // =0x1111503; CHECK-NEXT: movk w8, #17, lsl #16504; CHECK-NEXT: cmp w0, w8505; CHECK-NEXT: cset w0, lo506; CHECK-NEXT: ret507 %2 = icmp ult i32 %0, 1118481508 ret i1 %2509}510 511define i32 @accept_csel(i32 %0) {512; CHECK-SD-LABEL: accept_csel:513; CHECK-SD: // %bb.0:514; CHECK-SD-NEXT: sub w9, w0, #273, lsl #12 // =1118208515; CHECK-SD-NEXT: mov w8, #17 // =0x11516; CHECK-SD-NEXT: cmp w9, #273517; CHECK-SD-NEXT: mov w9, #11 // =0xb518; CHECK-SD-NEXT: csel w0, w9, w8, eq519; CHECK-SD-NEXT: ret520;521; CHECK-GI-LABEL: accept_csel:522; CHECK-GI: // %bb.0:523; CHECK-GI-NEXT: sub w8, w0, #273, lsl #12 // =1118208524; CHECK-GI-NEXT: mov w9, #17 // =0x11525; CHECK-GI-NEXT: mov w10, #11 // =0xb526; CHECK-GI-NEXT: cmp w8, #273527; CHECK-GI-NEXT: csel w0, w10, w9, eq528; CHECK-GI-NEXT: ret529 %2 = icmp eq i32 %0, 1118481530 %3 = select i1 %2, i32 11, i32 17531 ret i32 %3532}533 534define i32 @reject_non_eqne_csel(i32 %0) {535; CHECK-SD-LABEL: reject_non_eqne_csel:536; CHECK-SD: // %bb.0:537; CHECK-SD-NEXT: mov w8, #4369 // =0x1111538; CHECK-SD-NEXT: mov w9, #11 // =0xb539; CHECK-SD-NEXT: movk w8, #17, lsl #16540; CHECK-SD-NEXT: cmp w0, w8541; CHECK-SD-NEXT: mov w8, #17 // =0x11542; CHECK-SD-NEXT: csel w0, w9, w8, lo543; CHECK-SD-NEXT: ret544;545; CHECK-GI-LABEL: reject_non_eqne_csel:546; CHECK-GI: // %bb.0:547; CHECK-GI-NEXT: mov w8, #4369 // =0x1111548; CHECK-GI-NEXT: mov w9, #17 // =0x11549; CHECK-GI-NEXT: mov w10, #11 // =0xb550; CHECK-GI-NEXT: movk w8, #17, lsl #16551; CHECK-GI-NEXT: cmp w0, w8552; CHECK-GI-NEXT: csel w0, w10, w9, lo553; CHECK-GI-NEXT: ret554 %2 = icmp ult i32 %0, 1118481555 %3 = select i1 %2, i32 11, i32 17556 ret i32 %3557}558 559declare void @fooy()560 561define void @accept_branch(i32 %0) {562; CHECK-LABEL: accept_branch:563; CHECK: // %bb.0:564; CHECK-NEXT: sub w8, w0, #291, lsl #12 // =1191936565; CHECK-NEXT: cmp w8, #1110566; CHECK-NEXT: b.eq .LBB36_2567; CHECK-NEXT: // %bb.1:568; CHECK-NEXT: ret569; CHECK-NEXT: .LBB36_2:570; CHECK-NEXT: b fooy571 %2 = icmp ne i32 %0, 1193046572 br i1 %2, label %4, label %35733: ; preds = %1574 tail call void @fooy()575 br label %45764: ; preds = %3, %1577 ret void578}579 580define void @reject_non_eqne_branch(i32 %0) {581; CHECK-LABEL: reject_non_eqne_branch:582; CHECK: // %bb.0:583; CHECK-NEXT: mov w8, #13398 // =0x3456584; CHECK-NEXT: movk w8, #18, lsl #16585; CHECK-NEXT: cmp w0, w8586; CHECK-NEXT: b.le .LBB37_2587; CHECK-NEXT: // %bb.1:588; CHECK-NEXT: ret589; CHECK-NEXT: .LBB37_2:590; CHECK-NEXT: b fooy591 %2 = icmp sgt i32 %0, 1193046592 br i1 %2, label %4, label %35933: ; preds = %1594 tail call void @fooy()595 br label %45964: ; preds = %3, %1597 ret void598}599 600define i32 @reject_multiple_usages(i32 %0) {601; CHECK-SD-LABEL: reject_multiple_usages:602; CHECK-SD: // %bb.0:603; CHECK-SD-NEXT: mov w8, #4369 // =0x1111604; CHECK-SD-NEXT: mov w9, #3 // =0x3605; CHECK-SD-NEXT: mov w10, #17 // =0x11606; CHECK-SD-NEXT: movk w8, #17, lsl #16607; CHECK-SD-NEXT: mov w11, #12 // =0xc608; CHECK-SD-NEXT: cmp w0, w8609; CHECK-SD-NEXT: mov w8, #9 // =0x9610; CHECK-SD-NEXT: csel w8, w8, w9, eq611; CHECK-SD-NEXT: csel w9, w11, w10, hi612; CHECK-SD-NEXT: mov w10, #53312 // =0xd040613; CHECK-SD-NEXT: movk w10, #2, lsl #16614; CHECK-SD-NEXT: add w8, w8, w9615; CHECK-SD-NEXT: mov w9, #26304 // =0x66c0616; CHECK-SD-NEXT: cmp w0, w10617; CHECK-SD-NEXT: movk w9, #1433, lsl #16618; CHECK-SD-NEXT: csel w0, w8, w9, hi619; CHECK-SD-NEXT: ret620;621; CHECK-GI-LABEL: reject_multiple_usages:622; CHECK-GI: // %bb.0:623; CHECK-GI-NEXT: mov w8, #4369 // =0x1111624; CHECK-GI-NEXT: mov w9, #3 // =0x3625; CHECK-GI-NEXT: mov w10, #9 // =0x9626; CHECK-GI-NEXT: movk w8, #17, lsl #16627; CHECK-GI-NEXT: mov w11, #12 // =0xc628; CHECK-GI-NEXT: cmp w0, w8629; CHECK-GI-NEXT: mov w8, #17 // =0x11630; CHECK-GI-NEXT: csel w9, w10, w9, eq631; CHECK-GI-NEXT: csel w8, w11, w8, hi632; CHECK-GI-NEXT: mov w10, #53312 // =0xd040633; CHECK-GI-NEXT: movk w10, #2, lsl #16634; CHECK-GI-NEXT: add w8, w9, w8635; CHECK-GI-NEXT: mov w9, #26304 // =0x66c0636; CHECK-GI-NEXT: movk w9, #1433, lsl #16637; CHECK-GI-NEXT: cmp w0, w10638; CHECK-GI-NEXT: csel w0, w8, w9, hi639; CHECK-GI-NEXT: ret640 %2 = icmp eq i32 %0, 1118481641 %3 = icmp ugt i32 %0, 1118481642 %4 = select i1 %2, i32 9, i32 3643 %5 = select i1 %3, i32 12, i32 17644 %6 = add i32 %4, %5645 %7 = icmp ugt i32 %0, 184384646 %8 = select i1 %7, i32 %6, i32 93939392647 ret i32 %8648}649 650; Unique case found in ClangBuiltLinux where the DstReg is not Virtual and651; caused an assertion failure652define dso_local i32 @neigh_periodic_work_tbl_1() {653; CHECK-LABEL: neigh_periodic_work_tbl_1:654; CHECK: // %bb.0: // %entry655; CHECK-NEXT: adrp x8, neigh_periodic_work_tbl_1656; CHECK-NEXT: add x8, x8, :lo12:neigh_periodic_work_tbl_1657; CHECK-NEXT: add x8, x8, #18, lsl #12 // =73728658; CHECK-NEXT: cmn x8, #1272659; CHECK-NEXT: b.mi .LBB39_2660; CHECK-NEXT: // %bb.1: // %if.end661; CHECK-NEXT: ret662; CHECK-NEXT: .LBB39_2: // %for.cond663; CHECK-NEXT: // =>This Inner Loop Header: Depth=1664; CHECK-NEXT: b .LBB39_2665entry:666 %cmp = icmp slt i64 add (i64 ptrtoint (ptr @neigh_periodic_work_tbl_1 to i64), i64 75000), 0667 br i1 %cmp, label %for.cond, label %if.end668for.cond: ; preds = %entry, %for.cond669 br label %for.cond670if.end: ; preds = %entry671 ret i32 undef672}673 674@jiffies = dso_local local_unnamed_addr global i32 0, align 4675@primary_crng = dso_local local_unnamed_addr global i32 0, align 4676@input_pool = dso_local global i32 0, align 4677declare dso_local i32 @crng_reseed(...) local_unnamed_addr678; Function Attrs: nounwind uwtable679define dso_local i32 @_extract_crng_crng() {680; CHECK-LABEL: _extract_crng_crng:681; CHECK: // %bb.0: // %entry682; CHECK-NEXT: adrp x8, _extract_crng_crng683; CHECK-NEXT: add x8, x8, :lo12:_extract_crng_crng684; CHECK-NEXT: tbnz x8, #63, .LBB40_2685; CHECK-NEXT: // %bb.1: // %lor.lhs.false686; CHECK-NEXT: adrp x9, jiffies687; CHECK-NEXT: ldrsw x9, [x9, :lo12:jiffies]688; CHECK-NEXT: sub x8, x8, x9689; CHECK-NEXT: add x8, x8, #18, lsl #12 // =73728690; CHECK-NEXT: cmn x8, #1272691; CHECK-NEXT: b.pl .LBB40_3692; CHECK-NEXT: .LBB40_2: // %if.then693; CHECK-NEXT: adrp x8, primary_crng694; CHECK-NEXT: ldr w8, [x8, :lo12:primary_crng]695; CHECK-NEXT: cmp w8, #0696; CHECK-NEXT: adrp x8, input_pool697; CHECK-NEXT: add x8, x8, :lo12:input_pool698; CHECK-NEXT: csel x0, xzr, x8, eq699; CHECK-NEXT: b crng_reseed700; CHECK-NEXT: .LBB40_3: // %if.end701; CHECK-NEXT: ret702entry:703 %cmp2 = icmp slt ptr @_extract_crng_crng, null704 br i1 %cmp2, label %if.then, label %lor.lhs.false705lor.lhs.false: ; preds = %entry706 %0 = load i32, ptr @jiffies, align 4707 %idx.ext = sext i32 %0 to i64708 %idx.neg = sub nsw i64 0, %idx.ext709 %add.ptr = getelementptr i8, ptr getelementptr (i8, ptr @_extract_crng_crng, i64 75000), i64 %idx.neg710 %cmp = icmp slt ptr %add.ptr, null711 br i1 %cmp, label %if.then, label %if.end712if.then: ; preds = %lor.lhs.false, %entry713 %1 = load i32, ptr @primary_crng, align 4714 %tobool.not = icmp eq i32 %1, 0715 %cond = select i1 %tobool.not, ptr null, ptr @input_pool716 %call = tail call i32 @crng_reseed(ptr noundef %cond)717 br label %if.end718if.end: ; preds = %if.then, %lor.lhs.false719 ret i32 undef720}721 722; ((X << C) - Y) + Z --> (Z - Y) + (X << C)723define i32 @commute_subop0(i32 %x, i32 %y, i32 %z) {724; CHECK-SD-LABEL: commute_subop0:725; CHECK-SD: // %bb.0:726; CHECK-SD-NEXT: sub w8, w2, w1727; CHECK-SD-NEXT: add w0, w8, w0, lsl #3728; CHECK-SD-NEXT: ret729;730; CHECK-GI-LABEL: commute_subop0:731; CHECK-GI: // %bb.0:732; CHECK-GI-NEXT: lsl w8, w0, #3733; CHECK-GI-NEXT: sub w8, w8, w1734; CHECK-GI-NEXT: add w0, w8, w2735; CHECK-GI-NEXT: ret736 %shl = shl i32 %x, 3737 %sub = sub i32 %shl, %y738 %add = add i32 %sub, %z739 ret i32 %add740}741 742; ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)743define i32 @commute_subop0_lshr(i32 %x, i32 %y, i32 %z) {744; CHECK-SD-LABEL: commute_subop0_lshr:745; CHECK-SD: // %bb.0:746; CHECK-SD-NEXT: sub w8, w2, w1747; CHECK-SD-NEXT: add w0, w8, w0, lsr #3748; CHECK-SD-NEXT: ret749;750; CHECK-GI-LABEL: commute_subop0_lshr:751; CHECK-GI: // %bb.0:752; CHECK-GI-NEXT: lsr w8, w0, #3753; CHECK-GI-NEXT: sub w8, w8, w1754; CHECK-GI-NEXT: add w0, w8, w2755; CHECK-GI-NEXT: ret756 %lshr = lshr i32 %x, 3757 %sub = sub i32 %lshr, %y758 %add = add i32 %sub, %z759 ret i32 %add760}761 762; ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)763define i32 @commute_subop0_ashr(i32 %x, i32 %y, i32 %z) {764; CHECK-SD-LABEL: commute_subop0_ashr:765; CHECK-SD: // %bb.0:766; CHECK-SD-NEXT: sub w8, w2, w1767; CHECK-SD-NEXT: add w0, w8, w0, asr #3768; CHECK-SD-NEXT: ret769;770; CHECK-GI-LABEL: commute_subop0_ashr:771; CHECK-GI: // %bb.0:772; CHECK-GI-NEXT: asr w8, w0, #3773; CHECK-GI-NEXT: sub w8, w8, w1774; CHECK-GI-NEXT: add w0, w8, w2775; CHECK-GI-NEXT: ret776 %ashr = ashr i32 %x, 3777 %sub = sub i32 %ashr, %y778 %add = add i32 %sub, %z779 ret i32 %add780}781 782; ((sext X) - Y) + Z --> (Z - Y) + (sext X)783define i64 @commute_subop0_sext(i32 %x, i64 %y, i64 %z) {784; CHECK-SD-LABEL: commute_subop0_sext:785; CHECK-SD: // %bb.0:786; CHECK-SD-NEXT: sub x8, x2, x1787; CHECK-SD-NEXT: add x0, x8, w0, sxtw788; CHECK-SD-NEXT: ret789;790; CHECK-GI-LABEL: commute_subop0_sext:791; CHECK-GI: // %bb.0:792; CHECK-GI-NEXT: // kill: def $w0 killed $w0 def $x0793; CHECK-GI-NEXT: sxtw x8, w0794; CHECK-GI-NEXT: sub x8, x8, x1795; CHECK-GI-NEXT: add x0, x8, x2796; CHECK-GI-NEXT: ret797 %sext = sext i32 %x to i64798 %sub = sub i64 %sext, %y799 %add = add i64 %sub, %z800 ret i64 %add801}802 803; ((sext_inreg X) - Y) + Z --> (Z - Y) + (sext_inreg X)804define i64 @commute_subop0_sext_inreg(i64 %x, i64 %y, i64 %z) {805; CHECK-SD-LABEL: commute_subop0_sext_inreg:806; CHECK-SD: // %bb.0:807; CHECK-SD-NEXT: sub x8, x2, x1808; CHECK-SD-NEXT: add x0, x8, w0, sxth809; CHECK-SD-NEXT: ret810;811; CHECK-GI-LABEL: commute_subop0_sext_inreg:812; CHECK-GI: // %bb.0:813; CHECK-GI-NEXT: sxth x8, w0814; CHECK-GI-NEXT: sub x8, x8, x1815; CHECK-GI-NEXT: add x0, x8, x2816; CHECK-GI-NEXT: ret817 %shl = shl i64 %x, 48818 %ashr = ashr i64 %shl, 48819 %sub = sub i64 %ashr, %y820 %add = add i64 %sub, %z821 ret i64 %add822}823 824; ((zext X) - Y) + Z --> (Z - Y) + (zext X)825define i32 @commute_subop0_zext(i16 %x, i32 %y, i32 %z) {826; CHECK-SD-LABEL: commute_subop0_zext:827; CHECK-SD: // %bb.0:828; CHECK-SD-NEXT: sub w8, w2, w1829; CHECK-SD-NEXT: add w0, w8, w0, uxth830; CHECK-SD-NEXT: ret831;832; CHECK-GI-LABEL: commute_subop0_zext:833; CHECK-GI: // %bb.0:834; CHECK-GI-NEXT: and w8, w0, #0xffff835; CHECK-GI-NEXT: sub w8, w8, w1836; CHECK-GI-NEXT: add w0, w8, w2837; CHECK-GI-NEXT: ret838 %zext = zext i16 %x to i32839 %sub = sub i32 %zext, %y840 %add = add i32 %sub, %z841 ret i32 %add842}843 844 845; ((anyext X) - Y) + Z --> (Z - Y) + (anyext X)846define i8 @commute_subop0_anyext(i16 %a, i16 %b, i32 %c) {847; CHECK-SD-LABEL: commute_subop0_anyext:848; CHECK-SD: // %bb.0:849; CHECK-SD-NEXT: mov w8, #111 // =0x6f850; CHECK-SD-NEXT: sub w9, w2, w1851; CHECK-SD-NEXT: madd w8, w0, w8, w9852; CHECK-SD-NEXT: lsl w8, w8, #3853; CHECK-SD-NEXT: sub w0, w8, #1776854; CHECK-SD-NEXT: ret855;856; CHECK-GI-LABEL: commute_subop0_anyext:857; CHECK-GI: // %bb.0:858; CHECK-GI-NEXT: mov w8, #111 // =0x6f859; CHECK-GI-NEXT: add w9, w1, #222860; CHECK-GI-NEXT: mul w8, w0, w8861; CHECK-GI-NEXT: and w8, w8, #0xffff862; CHECK-GI-NEXT: sub w8, w8, w9, uxth863; CHECK-GI-NEXT: add w8, w8, w2864; CHECK-GI-NEXT: lsl w0, w8, #3865; CHECK-GI-NEXT: ret866 %aa = mul i16 %a, 111867 %bb = add i16 %b, 222868 %a_32 = zext i16 %aa to i32869 %b_32 = zext i16 %bb to i32870 %sub = sub i32 %a_32, %b_32871 %add = add i32 %sub, %c872 %trunc = trunc i32 %add to i8873 %r = shl i8 %trunc, 3874 ret i8 %r875}876 877; ((X and C) - Y) + Z --> (Z - Y) + (X and C)878define i32 @commute_subop0_and(i32 %x, i32 %y, i32 %z) {879; CHECK-SD-LABEL: commute_subop0_and:880; CHECK-SD: // %bb.0:881; CHECK-SD-NEXT: sub w8, w2, w1882; CHECK-SD-NEXT: add w0, w8, w0, uxtb883; CHECK-SD-NEXT: ret884;885; CHECK-GI-LABEL: commute_subop0_and:886; CHECK-GI: // %bb.0:887; CHECK-GI-NEXT: and w8, w0, #0xff888; CHECK-GI-NEXT: sub w8, w8, w1889; CHECK-GI-NEXT: add w0, w8, w2890; CHECK-GI-NEXT: ret891 %and = and i32 %x, 255892 %sub = sub i32 %and, %y893 %add = add i32 %sub, %z894 ret i32 %add895}896 897; Z + ((X << C) - Y) --> (Z - Y) + (X << C)898define i32 @commute_subop0_cadd(i32 %x, i32 %y, i32 %z) {899; CHECK-SD-LABEL: commute_subop0_cadd:900; CHECK-SD: // %bb.0:901; CHECK-SD-NEXT: sub w8, w2, w1902; CHECK-SD-NEXT: add w0, w8, w0, lsl #3903; CHECK-SD-NEXT: ret904;905; CHECK-GI-LABEL: commute_subop0_cadd:906; CHECK-GI: // %bb.0:907; CHECK-GI-NEXT: lsl w8, w0, #3908; CHECK-GI-NEXT: sub w8, w8, w1909; CHECK-GI-NEXT: add w0, w2, w8910; CHECK-GI-NEXT: ret911 %shl = shl i32 %x, 3912 %sub = sub i32 %shl, %y913 %add = add i32 %z, %sub914 ret i32 %add915}916 917; Y + ((X << C) - X) --> (Y - X) + (X << C)918define i32 @commute_subop0_mul(i32 %x, i32 %y) {919; CHECK-SD-LABEL: commute_subop0_mul:920; CHECK-SD: // %bb.0:921; CHECK-SD-NEXT: sub w8, w1, w0922; CHECK-SD-NEXT: add w0, w8, w0, lsl #3923; CHECK-SD-NEXT: ret924;925; CHECK-GI-LABEL: commute_subop0_mul:926; CHECK-GI: // %bb.0:927; CHECK-GI-NEXT: lsl w8, w0, #3928; CHECK-GI-NEXT: sub w8, w8, w0929; CHECK-GI-NEXT: add w0, w8, w1930; CHECK-GI-NEXT: ret931 %mul = mul i32 %x, 7932 %add = add i32 %mul, %y933 ret i32 %add934}935 936; negative case for ((X << C) - Y) + Z --> (Z - Y) + (X << C)937; Y can't be constant to avoid dead loop938define i32 @commute_subop0_zconst(i32 %x, i32 %y) {939; CHECK-LABEL: commute_subop0_zconst:940; CHECK: // %bb.0:941; CHECK-NEXT: lsl w8, w0, #3942; CHECK-NEXT: sub w8, w8, w1943; CHECK-NEXT: add w0, w8, #1944; CHECK-NEXT: ret945 %shl = shl i32 %x, 3946 %sub = sub i32 %shl, %y947 %add = add i32 %sub, 1948 ret i32 %add949}950 951; negative case for ((X << C) - Y) + Z --> (Z - Y) + (X << C)952; Y can't be shift C also to avoid dead loop953define i32 @commute_subop0_zshiftc_oneuse(i32 %x, i32 %y, i32 %z) {954; CHECK-LABEL: commute_subop0_zshiftc_oneuse:955; CHECK: // %bb.0:956; CHECK-NEXT: lsl w8, w0, #3957; CHECK-NEXT: sub w8, w8, w1958; CHECK-NEXT: add w0, w8, w2, lsl #2959; CHECK-NEXT: ret960 %xshl = shl i32 %x, 3961 %sub = sub i32 %xshl, %y962 %zshl = shl i32 %z, 2963 %add = add i32 %sub, %zshl964 ret i32 %add965}966 967define i32 @commute_subop0_zshiftc(i32 %x, i32 %y, i32 %z) {968; CHECK-SD-LABEL: commute_subop0_zshiftc:969; CHECK-SD: // %bb.0:970; CHECK-SD-NEXT: lsl w8, w2, #2971; CHECK-SD-NEXT: sub w9, w8, w1972; CHECK-SD-NEXT: add w9, w9, w0, lsl #3973; CHECK-SD-NEXT: eor w0, w8, w9974; CHECK-SD-NEXT: ret975;976; CHECK-GI-LABEL: commute_subop0_zshiftc:977; CHECK-GI: // %bb.0:978; CHECK-GI-NEXT: lsl w8, w0, #3979; CHECK-GI-NEXT: lsl w9, w2, #2980; CHECK-GI-NEXT: sub w8, w8, w1981; CHECK-GI-NEXT: add w8, w8, w9982; CHECK-GI-NEXT: eor w0, w9, w8983; CHECK-GI-NEXT: ret984 %xshl = shl i32 %x, 3985 %sub = sub i32 %xshl, %y986 %zshl = shl i32 %z, 2987 %add = add i32 %sub, %zshl988 %r = xor i32 %zshl, %add989 ret i32 %r990}991