diff options
Diffstat (limited to 'llvm/test/CodeGen/AArch64/addsub.ll')
-rw-r--r-- | llvm/test/CodeGen/AArch64/addsub.ll | 643 |
1 files changed, 377 insertions, 266 deletions
diff --git a/llvm/test/CodeGen/AArch64/addsub.ll b/llvm/test/CodeGen/AArch64/addsub.ll index 3a4955c..bb0d38a 100644 --- a/llvm/test/CodeGen/AArch64/addsub.ll +++ b/llvm/test/CodeGen/AArch64/addsub.ll @@ -1,50 +1,26 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-linux-gnu -verify-machineinstrs | FileCheck %s - -; Note that this should be refactored (for efficiency if nothing else) -; when the PCS is implemented so we don't have to worry about the -; loads and stores. - -@var_i32 = global i32 42 -@var2_i32 = global i32 43 -@var_i64 = global i64 0 +; RUN: llc -mtriple=aarch64-none-elf < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD +; RUN: llc -mtriple=aarch64-none-elf -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI ; Add pure 12-bit immediates: -define void @add_small() { -; CHECK-LABEL: add_small: -; CHECK: // %bb.0: -; CHECK-NEXT: adrp x8, :got:var_i32 -; CHECK-NEXT: adrp x9, :got:var_i64 -; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32] -; CHECK-NEXT: ldr x9, [x9, :got_lo12:var_i64] -; CHECK-NEXT: ldr w10, [x8] -; CHECK-NEXT: ldr x11, [x9] -; CHECK-NEXT: add w10, w10, #4095 -; CHECK-NEXT: add x11, x11, #52 -; CHECK-NEXT: str w10, [x8] -; CHECK-NEXT: str x11, [x9] -; CHECK-NEXT: ret - - %val32 = load i32, ptr @var_i32 +define i32 @add_small_i32(i32 %val32) { +; CHECK-LABEL: add_small_i32: +; CHECK: // %bb.0: +; CHECK-NEXT: add w0, w0, #4095 +; CHECK-NEXT: ret %newval32 = add i32 %val32, 4095 - store i32 %newval32, ptr @var_i32 + ret i32 %newval32 +} - %val64 = load i64, ptr @var_i64 +define i64 @add_small_i64(i64 %val64) { +; CHECK-LABEL: add_small_i64: +; CHECK: // %bb.0: +; CHECK-NEXT: add x0, x0, #52 +; CHECK-NEXT: ret %newval64 = add i64 %val64, 52 - store i64 %newval64, ptr @var_i64 - - ret void + ret i64 %newval64 } -; Make sure we grab the imm variant when the register operand -; can be implicitly zero-extend. -; We used to generate something horrible like this: -; wA = ldrb -; xB = ldimm 12 -; xC = add xB, wA, uxtb -; whereas this can be achieved with: -; wA = ldrb -; xC = add xA, #12 ; <- xA implicitly zero extend wA. define void @add_small_imm(ptr %p, ptr %q, i32 %b, ptr %addr) { ; CHECK-LABEL: add_small_imm: ; CHECK: // %bb.0: // %entry @@ -55,98 +31,71 @@ define void @add_small_imm(ptr %p, ptr %q, i32 %b, ptr %addr) { ; CHECK-NEXT: str x8, [x1] ; CHECK-NEXT: ret entry: - %t = load i8, ptr %p %promoted = zext i8 %t to i64 %zextt = zext i8 %t to i32 %add = add nuw i32 %zextt, %b - %add2 = add nuw i64 %promoted, 12 store i32 %add, ptr %addr - store i64 %add2, ptr %q ret void } ; Add 12-bit immediates, shifted left by 12 bits -define void @add_med() { -; CHECK-LABEL: add_med: -; CHECK: // %bb.0: -; CHECK-NEXT: adrp x8, :got:var_i32 -; CHECK-NEXT: adrp x9, :got:var_i64 -; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32] -; CHECK-NEXT: ldr x9, [x9, :got_lo12:var_i64] -; CHECK-NEXT: ldr w10, [x8] -; CHECK-NEXT: ldr x11, [x9] -; CHECK-NEXT: add w10, w10, #3567, lsl #12 // =14610432 -; CHECK-NEXT: add x11, x11, #4095, lsl #12 // =16773120 -; CHECK-NEXT: str w10, [x8] -; CHECK-NEXT: str x11, [x9] -; CHECK-NEXT: ret - - %val32 = load i32, ptr @var_i32 +define i32 @add_med_i32(i32 %val32) { +; CHECK-LABEL: add_med_i32: +; CHECK: // %bb.0: +; CHECK-NEXT: add w0, w0, #3567, lsl #12 // =14610432 +; CHECK-NEXT: ret %newval32 = add i32 %val32, 14610432 ; =0xdef000 - store i32 %newval32, ptr @var_i32 + ret i32 %newval32 +} - %val64 = load i64, ptr @var_i64 +define i64 @add_med_i64(i64 %val64) { +; CHECK-LABEL: add_med_i64: +; CHECK: // %bb.0: +; CHECK-NEXT: add x0, x0, #4095, lsl #12 // =16773120 +; CHECK-NEXT: ret %newval64 = add i64 %val64, 16773120 ; =0xfff000 - store i64 %newval64, ptr @var_i64 - - ret void + ret i64 %newval64 } ; Subtract 12-bit immediates -define void @sub_small() { -; CHECK-LABEL: sub_small: -; CHECK: // %bb.0: -; CHECK-NEXT: adrp x8, :got:var_i32 -; CHECK-NEXT: adrp x9, :got:var_i64 -; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32] -; CHECK-NEXT: ldr x9, [x9, :got_lo12:var_i64] -; CHECK-NEXT: ldr w10, [x8] -; CHECK-NEXT: ldr x11, [x9] -; CHECK-NEXT: sub w10, w10, #4095 -; CHECK-NEXT: sub x11, x11, #52 -; CHECK-NEXT: str w10, [x8] -; CHECK-NEXT: str x11, [x9] -; CHECK-NEXT: ret - - %val32 = load i32, ptr @var_i32 +define i32 @sub_small_i32(i32 %val32) { +; CHECK-LABEL: sub_small_i32: +; CHECK: // %bb.0: +; CHECK-NEXT: sub w0, w0, #4095 +; CHECK-NEXT: ret %newval32 = sub i32 %val32, 4095 - store i32 %newval32, ptr @var_i32 + ret i32 %newval32 +} - %val64 = load i64, ptr @var_i64 +define i64 @sub_small_i64(i64 %val64) { +; CHECK-LABEL: sub_small_i64: +; CHECK: // %bb.0: +; CHECK-NEXT: sub x0, x0, #52 +; CHECK-NEXT: ret %newval64 = sub i64 %val64, 52 - store i64 %newval64, ptr @var_i64 - - ret void + ret i64 %newval64 } ; Subtract 12-bit immediates, shifted left by 12 bits -define void @sub_med() { -; CHECK-LABEL: sub_med: -; CHECK: // %bb.0: -; CHECK-NEXT: adrp x8, :got:var_i32 -; CHECK-NEXT: adrp x9, :got:var_i64 -; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32] -; CHECK-NEXT: ldr x9, [x9, :got_lo12:var_i64] -; CHECK-NEXT: ldr w10, [x8] -; CHECK-NEXT: ldr x11, [x9] -; CHECK-NEXT: sub w10, w10, #3567, lsl #12 // =14610432 -; CHECK-NEXT: sub x11, x11, #4095, lsl #12 // =16773120 -; CHECK-NEXT: str w10, [x8] -; CHECK-NEXT: str x11, [x9] -; CHECK-NEXT: ret - - %val32 = load i32, ptr @var_i32 +define i32 @sub_med_i32(i32 %val32) { +; CHECK-LABEL: sub_med_i32: +; CHECK: // %bb.0: +; CHECK-NEXT: sub w0, w0, #3567, lsl #12 // =14610432 +; CHECK-NEXT: ret %newval32 = sub i32 %val32, 14610432 ; =0xdef000 - store i32 %newval32, ptr @var_i32 + ret i32 %newval32 +} - %val64 = load i64, ptr @var_i64 +define i64 @sub_med_i64(i64 %val64) { +; CHECK-LABEL: sub_med_i64: +; CHECK: // %bb.0: +; CHECK-NEXT: sub x0, x0, #4095, lsl #12 // =16773120 +; CHECK-NEXT: ret %newval64 = sub i64 %val64, 16773120 ; =0xfff000 - store i64 %newval64, ptr @var_i64 - - ret void + ret i64 %newval64 } define i64 @add_two_parts_imm_i64(i64 %a) { @@ -261,10 +210,10 @@ define void @add_in_loop(i32 %0) { ; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: mov w19, #43690 // =0xaaaa ; CHECK-NEXT: movk w19, #170, lsl #16 -; CHECK-NEXT: .LBB15_1: // =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: .LBB19_1: // =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: add w0, w0, w19 ; CHECK-NEXT: bl foox -; CHECK-NEXT: b .LBB15_1 +; CHECK-NEXT: b .LBB19_1 br label %2 2: %3 = phi i32 [ %0, %1 ], [ %5, %2 ] @@ -273,75 +222,103 @@ define void @add_in_loop(i32 %0) { br label %2 } -define void @testing() { -; CHECK-LABEL: testing: -; CHECK: // %bb.0: -; CHECK-NEXT: adrp x8, :got:var_i32 -; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32] -; CHECK-NEXT: ldr w9, [x8] -; CHECK-NEXT: cmp w9, #4095 -; CHECK-NEXT: b.ne .LBB16_6 -; CHECK-NEXT: // %bb.1: // %test2 -; CHECK-NEXT: adrp x10, :got:var2_i32 -; CHECK-NEXT: add w11, w9, #1 -; CHECK-NEXT: ldr x10, [x10, :got_lo12:var2_i32] -; CHECK-NEXT: str w11, [x8] -; CHECK-NEXT: ldr w10, [x10] -; CHECK-NEXT: cmp w10, #3567, lsl #12 // =14610432 -; CHECK-NEXT: b.lo .LBB16_6 -; CHECK-NEXT: // %bb.2: // %test3 -; CHECK-NEXT: add w11, w9, #2 -; CHECK-NEXT: cmp w9, #123 -; CHECK-NEXT: str w11, [x8] -; CHECK-NEXT: b.lt .LBB16_6 -; CHECK-NEXT: // %bb.3: // %test4 -; CHECK-NEXT: add w11, w9, #3 -; CHECK-NEXT: cmp w10, #321 -; CHECK-NEXT: str w11, [x8] -; CHECK-NEXT: b.gt .LBB16_6 -; CHECK-NEXT: // %bb.4: // %test5 -; CHECK-NEXT: add w11, w9, #4 -; CHECK-NEXT: cmn w10, #443 -; CHECK-NEXT: str w11, [x8] -; CHECK-NEXT: b.ge .LBB16_6 -; CHECK-NEXT: // %bb.5: // %test6 -; CHECK-NEXT: add w9, w9, #5 -; CHECK-NEXT: str w9, [x8] -; CHECK-NEXT: .LBB16_6: // %common.ret -; CHECK-NEXT: ret - %val = load i32, ptr @var_i32 - %val2 = load i32, ptr @var2_i32 +define void @testing(ptr %var_i32, ptr %var2_i32) { +; CHECK-SD-LABEL: testing: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: ldr w8, [x0] +; CHECK-SD-NEXT: cmp w8, #4095 +; CHECK-SD-NEXT: b.ne .LBB20_6 +; CHECK-SD-NEXT: // %bb.1: // %test2 +; CHECK-SD-NEXT: ldr w9, [x1] +; CHECK-SD-NEXT: add w10, w8, #1 +; CHECK-SD-NEXT: str w10, [x0] +; CHECK-SD-NEXT: cmp w9, #3567, lsl #12 // =14610432 +; CHECK-SD-NEXT: b.lo .LBB20_6 +; CHECK-SD-NEXT: // %bb.2: // %test3 +; CHECK-SD-NEXT: add w10, w8, #2 +; CHECK-SD-NEXT: cmp w8, #123 +; CHECK-SD-NEXT: str w10, [x0] +; CHECK-SD-NEXT: b.lt .LBB20_6 +; CHECK-SD-NEXT: // %bb.3: // %test4 +; CHECK-SD-NEXT: add w10, w8, #3 +; CHECK-SD-NEXT: cmp w9, #321 +; CHECK-SD-NEXT: str w10, [x0] +; CHECK-SD-NEXT: b.gt .LBB20_6 +; CHECK-SD-NEXT: // %bb.4: // %test5 +; CHECK-SD-NEXT: add w10, w8, #4 +; CHECK-SD-NEXT: cmn w9, #443 +; CHECK-SD-NEXT: str w10, [x0] +; CHECK-SD-NEXT: b.ge .LBB20_6 +; CHECK-SD-NEXT: // %bb.5: // %test6 +; CHECK-SD-NEXT: add w8, w8, #5 +; CHECK-SD-NEXT: str w8, [x0] +; CHECK-SD-NEXT: .LBB20_6: // %common.ret +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: testing: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: ldr w8, [x0] +; CHECK-GI-NEXT: cmp w8, #4095 +; CHECK-GI-NEXT: b.ne .LBB20_6 +; CHECK-GI-NEXT: // %bb.1: // %test2 +; CHECK-GI-NEXT: ldr w9, [x1] +; CHECK-GI-NEXT: add w10, w8, #1 +; CHECK-GI-NEXT: str w10, [x0] +; CHECK-GI-NEXT: cmp w9, #3567, lsl #12 // =14610432 +; CHECK-GI-NEXT: b.lo .LBB20_6 +; CHECK-GI-NEXT: // %bb.2: // %test3 +; CHECK-GI-NEXT: add w10, w8, #2 +; CHECK-GI-NEXT: cmp w8, #123 +; CHECK-GI-NEXT: str w10, [x0] +; CHECK-GI-NEXT: b.lt .LBB20_6 +; CHECK-GI-NEXT: // %bb.3: // %test4 +; CHECK-GI-NEXT: add w10, w8, #3 +; CHECK-GI-NEXT: cmp w9, #321 +; CHECK-GI-NEXT: str w10, [x0] +; CHECK-GI-NEXT: b.gt .LBB20_6 +; CHECK-GI-NEXT: // %bb.4: // %test5 +; CHECK-GI-NEXT: add w10, w8, #4 +; CHECK-GI-NEXT: cmn w9, #444 +; CHECK-GI-NEXT: str w10, [x0] +; CHECK-GI-NEXT: b.gt .LBB20_6 +; CHECK-GI-NEXT: // %bb.5: // %test6 +; CHECK-GI-NEXT: add w8, w8, #5 +; CHECK-GI-NEXT: str w8, [x0] +; CHECK-GI-NEXT: .LBB20_6: // %common.ret +; CHECK-GI-NEXT: ret + %val = load i32, ptr %var_i32 + %val2 = load i32, ptr %var2_i32 %cmp_pos_small = icmp ne i32 %val, 4095 br i1 %cmp_pos_small, label %ret, label %test2 test2: %newval2 = add i32 %val, 1 - store i32 %newval2, ptr @var_i32 + store i32 %newval2, ptr %var_i32 %cmp_pos_big = icmp ult i32 %val2, 14610432 br i1 %cmp_pos_big, label %ret, label %test3 test3: %newval3 = add i32 %val, 2 - store i32 %newval3, ptr @var_i32 + store i32 %newval3, ptr %var_i32 %cmp_pos_slt = icmp slt i32 %val, 123 br i1 %cmp_pos_slt, label %ret, label %test4 test4: %newval4 = add i32 %val, 3 - store i32 %newval4, ptr @var_i32 + store i32 %newval4, ptr %var_i32 %cmp_pos_sgt = icmp sgt i32 %val2, 321 br i1 %cmp_pos_sgt, label %ret, label %test5 test5: %newval5 = add i32 %val, 4 - store i32 %newval5, ptr @var_i32 + store i32 %newval5, ptr %var_i32 %cmp_neg_uge = icmp sgt i32 %val2, -444 br i1 %cmp_neg_uge, label %ret, label %test6 test6: %newval6 = add i32 %val, 5 - store i32 %newval6, ptr @var_i32 + store i32 %newval6, ptr %var_i32 ret void ret: @@ -371,15 +348,26 @@ define i1 @sadd_add(i32 %a, i32 %b, ptr %p) { declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b) define i1 @uadd_add(i8 %a, i8 %b, ptr %p) { -; CHECK-LABEL: uadd_add: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #255 // =0xff -; CHECK-NEXT: bic w8, w8, w0 -; CHECK-NEXT: add w8, w8, w1, uxtb -; CHECK-NEXT: lsr w0, w8, #8 -; CHECK-NEXT: add w8, w8, #1 -; CHECK-NEXT: strb w8, [x2] -; CHECK-NEXT: ret +; CHECK-SD-LABEL: uadd_add: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: mov w8, #255 // =0xff +; CHECK-SD-NEXT: bic w8, w8, w0 +; CHECK-SD-NEXT: add w8, w8, w1, uxtb +; CHECK-SD-NEXT: lsr w0, w8, #8 +; CHECK-SD-NEXT: add w8, w8, #1 +; CHECK-SD-NEXT: strb w8, [x2] +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: uadd_add: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: mvn w8, w0 +; CHECK-GI-NEXT: and w9, w1, #0xff +; CHECK-GI-NEXT: add w8, w9, w8, uxtb +; CHECK-GI-NEXT: cmp w8, w8, uxtb +; CHECK-GI-NEXT: add w8, w8, #1 +; CHECK-GI-NEXT: cset w0, ne +; CHECK-GI-NEXT: strb w8, [x2] +; CHECK-GI-NEXT: ret %nota = xor i8 %a, -1 %a0 = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %nota, i8 %b) %e0 = extractvalue {i8, i1} %a0, 0 @@ -521,29 +509,48 @@ define i1 @reject_non_eqne_csinc(i32 %0) { } define i32 @accept_csel(i32 %0) { -; CHECK-LABEL: accept_csel: -; CHECK: // %bb.0: -; CHECK-NEXT: sub w9, w0, #273, lsl #12 // =1118208 -; CHECK-NEXT: mov w8, #17 // =0x11 -; CHECK-NEXT: cmp w9, #273 -; CHECK-NEXT: mov w9, #11 // =0xb -; CHECK-NEXT: csel w0, w9, w8, eq -; CHECK-NEXT: ret +; CHECK-SD-LABEL: accept_csel: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub w9, w0, #273, lsl #12 // =1118208 +; CHECK-SD-NEXT: mov w8, #17 // =0x11 +; CHECK-SD-NEXT: cmp w9, #273 +; CHECK-SD-NEXT: mov w9, #11 // =0xb +; CHECK-SD-NEXT: csel w0, w9, w8, eq +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: accept_csel: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: sub w8, w0, #273, lsl #12 // =1118208 +; CHECK-GI-NEXT: mov w9, #17 // =0x11 +; CHECK-GI-NEXT: mov w10, #11 // =0xb +; CHECK-GI-NEXT: cmp w8, #273 +; CHECK-GI-NEXT: csel w0, w10, w9, eq +; CHECK-GI-NEXT: ret %2 = icmp eq i32 %0, 1118481 %3 = select i1 %2, i32 11, i32 17 ret i32 %3 } define i32 @reject_non_eqne_csel(i32 %0) { -; CHECK-LABEL: reject_non_eqne_csel: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #4369 // =0x1111 -; CHECK-NEXT: mov w9, #11 // =0xb -; CHECK-NEXT: movk w8, #17, lsl #16 -; CHECK-NEXT: cmp w0, w8 -; CHECK-NEXT: mov w8, #17 // =0x11 -; CHECK-NEXT: csel w0, w9, w8, lo -; CHECK-NEXT: ret +; CHECK-SD-LABEL: reject_non_eqne_csel: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: mov w8, #4369 // =0x1111 +; CHECK-SD-NEXT: mov w9, #11 // =0xb +; CHECK-SD-NEXT: movk w8, #17, lsl #16 +; CHECK-SD-NEXT: cmp w0, w8 +; CHECK-SD-NEXT: mov w8, #17 // =0x11 +; CHECK-SD-NEXT: csel w0, w9, w8, lo +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: reject_non_eqne_csel: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: mov w8, #4369 // =0x1111 +; CHECK-GI-NEXT: mov w9, #17 // =0x11 +; CHECK-GI-NEXT: mov w10, #11 // =0xb +; CHECK-GI-NEXT: movk w8, #17, lsl #16 +; CHECK-GI-NEXT: cmp w0, w8 +; CHECK-GI-NEXT: csel w0, w10, w9, lo +; CHECK-GI-NEXT: ret %2 = icmp ult i32 %0, 1118481 %3 = select i1 %2, i32 11, i32 17 ret i32 %3 @@ -556,10 +563,10 @@ define void @accept_branch(i32 %0) { ; CHECK: // %bb.0: ; CHECK-NEXT: sub w8, w0, #291, lsl #12 // =1191936 ; CHECK-NEXT: cmp w8, #1110 -; CHECK-NEXT: b.eq .LBB32_2 +; CHECK-NEXT: b.eq .LBB36_2 ; CHECK-NEXT: // %bb.1: ; CHECK-NEXT: ret -; CHECK-NEXT: .LBB32_2: +; CHECK-NEXT: .LBB36_2: ; CHECK-NEXT: b fooy %2 = icmp ne i32 %0, 1193046 br i1 %2, label %4, label %3 @@ -576,10 +583,10 @@ define void @reject_non_eqne_branch(i32 %0) { ; CHECK-NEXT: mov w8, #13398 // =0x3456 ; CHECK-NEXT: movk w8, #18, lsl #16 ; CHECK-NEXT: cmp w0, w8 -; CHECK-NEXT: b.le .LBB33_2 +; CHECK-NEXT: b.le .LBB37_2 ; CHECK-NEXT: // %bb.1: ; CHECK-NEXT: ret -; CHECK-NEXT: .LBB33_2: +; CHECK-NEXT: .LBB37_2: ; CHECK-NEXT: b fooy %2 = icmp sgt i32 %0, 1193046 br i1 %2, label %4, label %3 @@ -591,25 +598,45 @@ define void @reject_non_eqne_branch(i32 %0) { } define i32 @reject_multiple_usages(i32 %0) { -; CHECK-LABEL: reject_multiple_usages: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #4369 // =0x1111 -; CHECK-NEXT: mov w9, #3 // =0x3 -; CHECK-NEXT: mov w10, #17 // =0x11 -; CHECK-NEXT: movk w8, #17, lsl #16 -; CHECK-NEXT: mov w11, #12 // =0xc -; CHECK-NEXT: cmp w0, w8 -; CHECK-NEXT: mov w8, #9 // =0x9 -; CHECK-NEXT: csel w8, w8, w9, eq -; CHECK-NEXT: csel w9, w11, w10, hi -; CHECK-NEXT: mov w10, #53312 // =0xd040 -; CHECK-NEXT: movk w10, #2, lsl #16 -; CHECK-NEXT: add w8, w8, w9 -; CHECK-NEXT: mov w9, #26304 // =0x66c0 -; CHECK-NEXT: cmp w0, w10 -; CHECK-NEXT: movk w9, #1433, lsl #16 -; CHECK-NEXT: csel w0, w8, w9, hi -; CHECK-NEXT: ret +; CHECK-SD-LABEL: reject_multiple_usages: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: mov w8, #4369 // =0x1111 +; CHECK-SD-NEXT: mov w9, #3 // =0x3 +; CHECK-SD-NEXT: mov w10, #17 // =0x11 +; CHECK-SD-NEXT: movk w8, #17, lsl #16 +; CHECK-SD-NEXT: mov w11, #12 // =0xc +; CHECK-SD-NEXT: cmp w0, w8 +; CHECK-SD-NEXT: mov w8, #9 // =0x9 +; CHECK-SD-NEXT: csel w8, w8, w9, eq +; CHECK-SD-NEXT: csel w9, w11, w10, hi +; CHECK-SD-NEXT: mov w10, #53312 // =0xd040 +; CHECK-SD-NEXT: movk w10, #2, lsl #16 +; CHECK-SD-NEXT: add w8, w8, w9 +; CHECK-SD-NEXT: mov w9, #26304 // =0x66c0 +; CHECK-SD-NEXT: cmp w0, w10 +; CHECK-SD-NEXT: movk w9, #1433, lsl #16 +; CHECK-SD-NEXT: csel w0, w8, w9, hi +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: reject_multiple_usages: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: mov w8, #4369 // =0x1111 +; CHECK-GI-NEXT: mov w9, #3 // =0x3 +; CHECK-GI-NEXT: mov w10, #9 // =0x9 +; CHECK-GI-NEXT: movk w8, #17, lsl #16 +; CHECK-GI-NEXT: mov w11, #12 // =0xc +; CHECK-GI-NEXT: cmp w0, w8 +; CHECK-GI-NEXT: mov w8, #17 // =0x11 +; CHECK-GI-NEXT: csel w9, w10, w9, eq +; CHECK-GI-NEXT: csel w8, w11, w8, hi +; CHECK-GI-NEXT: mov w10, #53312 // =0xd040 +; CHECK-GI-NEXT: movk w10, #2, lsl #16 +; CHECK-GI-NEXT: add w8, w9, w8 +; CHECK-GI-NEXT: mov w9, #26304 // =0x66c0 +; CHECK-GI-NEXT: movk w9, #1433, lsl #16 +; CHECK-GI-NEXT: cmp w0, w10 +; CHECK-GI-NEXT: csel w0, w8, w9, hi +; CHECK-GI-NEXT: ret %2 = icmp eq i32 %0, 1118481 %3 = icmp ugt i32 %0, 1118481 %4 = select i1 %2, i32 9, i32 3 @@ -629,12 +656,12 @@ define dso_local i32 @neigh_periodic_work_tbl_1() { ; CHECK-NEXT: add x8, x8, :lo12:neigh_periodic_work_tbl_1 ; CHECK-NEXT: add x8, x8, #18, lsl #12 // =73728 ; CHECK-NEXT: cmn x8, #1272 -; CHECK-NEXT: b.mi .LBB35_2 +; CHECK-NEXT: b.mi .LBB39_2 ; CHECK-NEXT: // %bb.1: // %if.end ; CHECK-NEXT: ret -; CHECK-NEXT: .LBB35_2: // %for.cond +; CHECK-NEXT: .LBB39_2: // %for.cond ; CHECK-NEXT: // =>This Inner Loop Header: Depth=1 -; CHECK-NEXT: b .LBB35_2 +; CHECK-NEXT: b .LBB39_2 entry: %cmp = icmp slt i64 add (i64 ptrtoint (ptr @neigh_periodic_work_tbl_1 to i64), i64 75000), 0 br i1 %cmp, label %for.cond, label %if.end @@ -654,15 +681,15 @@ define dso_local i32 @_extract_crng_crng() { ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adrp x8, _extract_crng_crng ; CHECK-NEXT: add x8, x8, :lo12:_extract_crng_crng -; CHECK-NEXT: tbnz x8, #63, .LBB36_2 +; CHECK-NEXT: tbnz x8, #63, .LBB40_2 ; CHECK-NEXT: // %bb.1: // %lor.lhs.false ; CHECK-NEXT: adrp x9, jiffies ; CHECK-NEXT: ldrsw x9, [x9, :lo12:jiffies] ; CHECK-NEXT: sub x8, x8, x9 ; CHECK-NEXT: add x8, x8, #18, lsl #12 // =73728 ; CHECK-NEXT: cmn x8, #1272 -; CHECK-NEXT: b.pl .LBB36_3 -; CHECK-NEXT: .LBB36_2: // %if.then +; CHECK-NEXT: b.pl .LBB40_3 +; CHECK-NEXT: .LBB40_2: // %if.then ; CHECK-NEXT: adrp x8, primary_crng ; CHECK-NEXT: ldr w8, [x8, :lo12:primary_crng] ; CHECK-NEXT: cmp w8, #0 @@ -670,7 +697,7 @@ define dso_local i32 @_extract_crng_crng() { ; CHECK-NEXT: add x8, x8, :lo12:input_pool ; CHECK-NEXT: csel x0, xzr, x8, eq ; CHECK-NEXT: b crng_reseed -; CHECK-NEXT: .LBB36_3: // %if.end +; CHECK-NEXT: .LBB40_3: // %if.end ; CHECK-NEXT: ret entry: %cmp2 = icmp slt ptr @_extract_crng_crng, null @@ -694,11 +721,18 @@ if.end: ; preds = %if.then, %lor.lhs.f ; ((X << C) - Y) + Z --> (Z - Y) + (X << C) define i32 @commute_subop0(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: commute_subop0: -; CHECK: // %bb.0: -; CHECK-NEXT: sub w8, w2, w1 -; CHECK-NEXT: add w0, w8, w0, lsl #3 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub w8, w2, w1 +; CHECK-SD-NEXT: add w0, w8, w0, lsl #3 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: lsl w8, w0, #3 +; CHECK-GI-NEXT: sub w8, w8, w1 +; CHECK-GI-NEXT: add w0, w8, w2 +; CHECK-GI-NEXT: ret %shl = shl i32 %x, 3 %sub = sub i32 %shl, %y %add = add i32 %sub, %z @@ -707,11 +741,18 @@ define i32 @commute_subop0(i32 %x, i32 %y, i32 %z) { ; ((X >> C) - Y) + Z --> (Z - Y) + (X >> C) define i32 @commute_subop0_lshr(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: commute_subop0_lshr: -; CHECK: // %bb.0: -; CHECK-NEXT: sub w8, w2, w1 -; CHECK-NEXT: add w0, w8, w0, lsr #3 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_lshr: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub w8, w2, w1 +; CHECK-SD-NEXT: add w0, w8, w0, lsr #3 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_lshr: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: lsr w8, w0, #3 +; CHECK-GI-NEXT: sub w8, w8, w1 +; CHECK-GI-NEXT: add w0, w8, w2 +; CHECK-GI-NEXT: ret %lshr = lshr i32 %x, 3 %sub = sub i32 %lshr, %y %add = add i32 %sub, %z @@ -720,11 +761,18 @@ define i32 @commute_subop0_lshr(i32 %x, i32 %y, i32 %z) { ; ((X >> C) - Y) + Z --> (Z - Y) + (X >> C) define i32 @commute_subop0_ashr(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: commute_subop0_ashr: -; CHECK: // %bb.0: -; CHECK-NEXT: sub w8, w2, w1 -; CHECK-NEXT: add w0, w8, w0, asr #3 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_ashr: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub w8, w2, w1 +; CHECK-SD-NEXT: add w0, w8, w0, asr #3 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_ashr: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: asr w8, w0, #3 +; CHECK-GI-NEXT: sub w8, w8, w1 +; CHECK-GI-NEXT: add w0, w8, w2 +; CHECK-GI-NEXT: ret %ashr = ashr i32 %x, 3 %sub = sub i32 %ashr, %y %add = add i32 %sub, %z @@ -733,11 +781,19 @@ define i32 @commute_subop0_ashr(i32 %x, i32 %y, i32 %z) { ; ((sext X) - Y) + Z --> (Z - Y) + (sext X) define i64 @commute_subop0_sext(i32 %x, i64 %y, i64 %z) { -; CHECK-LABEL: commute_subop0_sext: -; CHECK: // %bb.0: -; CHECK-NEXT: sub x8, x2, x1 -; CHECK-NEXT: add x0, x8, w0, sxtw -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_sext: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub x8, x2, x1 +; CHECK-SD-NEXT: add x0, x8, w0, sxtw +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_sext: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: // kill: def $w0 killed $w0 def $x0 +; CHECK-GI-NEXT: sxtw x8, w0 +; CHECK-GI-NEXT: sub x8, x8, x1 +; CHECK-GI-NEXT: add x0, x8, x2 +; CHECK-GI-NEXT: ret %sext = sext i32 %x to i64 %sub = sub i64 %sext, %y %add = add i64 %sub, %z @@ -746,11 +802,18 @@ define i64 @commute_subop0_sext(i32 %x, i64 %y, i64 %z) { ; ((sext_inreg X) - Y) + Z --> (Z - Y) + (sext_inreg X) define i64 @commute_subop0_sext_inreg(i64 %x, i64 %y, i64 %z) { -; CHECK-LABEL: commute_subop0_sext_inreg: -; CHECK: // %bb.0: -; CHECK-NEXT: sub x8, x2, x1 -; CHECK-NEXT: add x0, x8, w0, sxth -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_sext_inreg: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub x8, x2, x1 +; CHECK-SD-NEXT: add x0, x8, w0, sxth +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_sext_inreg: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: sxth x8, w0 +; CHECK-GI-NEXT: sub x8, x8, x1 +; CHECK-GI-NEXT: add x0, x8, x2 +; CHECK-GI-NEXT: ret %shl = shl i64 %x, 48 %ashr = ashr i64 %shl, 48 %sub = sub i64 %ashr, %y @@ -760,11 +823,18 @@ define i64 @commute_subop0_sext_inreg(i64 %x, i64 %y, i64 %z) { ; ((zext X) - Y) + Z --> (Z - Y) + (zext X) define i32 @commute_subop0_zext(i16 %x, i32 %y, i32 %z) { -; CHECK-LABEL: commute_subop0_zext: -; CHECK: // %bb.0: -; CHECK-NEXT: sub w8, w2, w1 -; CHECK-NEXT: add w0, w8, w0, uxth -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_zext: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub w8, w2, w1 +; CHECK-SD-NEXT: add w0, w8, w0, uxth +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_zext: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: and w8, w0, #0xffff +; CHECK-GI-NEXT: sub w8, w8, w1 +; CHECK-GI-NEXT: add w0, w8, w2 +; CHECK-GI-NEXT: ret %zext = zext i16 %x to i32 %sub = sub i32 %zext, %y %add = add i32 %sub, %z @@ -774,14 +844,25 @@ define i32 @commute_subop0_zext(i16 %x, i32 %y, i32 %z) { ; ((anyext X) - Y) + Z --> (Z - Y) + (anyext X) define i8 @commute_subop0_anyext(i16 %a, i16 %b, i32 %c) { -; CHECK-LABEL: commute_subop0_anyext: -; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #111 // =0x6f -; CHECK-NEXT: sub w9, w2, w1 -; CHECK-NEXT: madd w8, w0, w8, w9 -; CHECK-NEXT: lsl w8, w8, #3 -; CHECK-NEXT: sub w0, w8, #1776 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_anyext: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: mov w8, #111 // =0x6f +; CHECK-SD-NEXT: sub w9, w2, w1 +; CHECK-SD-NEXT: madd w8, w0, w8, w9 +; CHECK-SD-NEXT: lsl w8, w8, #3 +; CHECK-SD-NEXT: sub w0, w8, #1776 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_anyext: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: mov w8, #111 // =0x6f +; CHECK-GI-NEXT: add w9, w1, #222 +; CHECK-GI-NEXT: mul w8, w0, w8 +; CHECK-GI-NEXT: and w8, w8, #0xffff +; CHECK-GI-NEXT: sub w8, w8, w9, uxth +; CHECK-GI-NEXT: add w8, w8, w2 +; CHECK-GI-NEXT: lsl w0, w8, #3 +; CHECK-GI-NEXT: ret %aa = mul i16 %a, 111 %bb = add i16 %b, 222 %a_32 = zext i16 %aa to i32 @@ -795,11 +876,18 @@ define i8 @commute_subop0_anyext(i16 %a, i16 %b, i32 %c) { ; ((X and C) - Y) + Z --> (Z - Y) + (X and C) define i32 @commute_subop0_and(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: commute_subop0_and: -; CHECK: // %bb.0: -; CHECK-NEXT: sub w8, w2, w1 -; CHECK-NEXT: add w0, w8, w0, uxtb -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_and: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub w8, w2, w1 +; CHECK-SD-NEXT: add w0, w8, w0, uxtb +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_and: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: and w8, w0, #0xff +; CHECK-GI-NEXT: sub w8, w8, w1 +; CHECK-GI-NEXT: add w0, w8, w2 +; CHECK-GI-NEXT: ret %and = and i32 %x, 255 %sub = sub i32 %and, %y %add = add i32 %sub, %z @@ -808,11 +896,18 @@ define i32 @commute_subop0_and(i32 %x, i32 %y, i32 %z) { ; Z + ((X << C) - Y) --> (Z - Y) + (X << C) define i32 @commute_subop0_cadd(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: commute_subop0_cadd: -; CHECK: // %bb.0: -; CHECK-NEXT: sub w8, w2, w1 -; CHECK-NEXT: add w0, w8, w0, lsl #3 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_cadd: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub w8, w2, w1 +; CHECK-SD-NEXT: add w0, w8, w0, lsl #3 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_cadd: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: lsl w8, w0, #3 +; CHECK-GI-NEXT: sub w8, w8, w1 +; CHECK-GI-NEXT: add w0, w2, w8 +; CHECK-GI-NEXT: ret %shl = shl i32 %x, 3 %sub = sub i32 %shl, %y %add = add i32 %z, %sub @@ -821,11 +916,18 @@ define i32 @commute_subop0_cadd(i32 %x, i32 %y, i32 %z) { ; Y + ((X << C) - X) --> (Y - X) + (X << C) define i32 @commute_subop0_mul(i32 %x, i32 %y) { -; CHECK-LABEL: commute_subop0_mul: -; CHECK: // %bb.0: -; CHECK-NEXT: sub w8, w1, w0 -; CHECK-NEXT: add w0, w8, w0, lsl #3 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_mul: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: sub w8, w1, w0 +; CHECK-SD-NEXT: add w0, w8, w0, lsl #3 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_mul: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: lsl w8, w0, #3 +; CHECK-GI-NEXT: sub w8, w8, w0 +; CHECK-GI-NEXT: add w0, w8, w1 +; CHECK-GI-NEXT: ret %mul = mul i32 %x, 7 %add = add i32 %mul, %y ret i32 %add @@ -863,13 +965,22 @@ define i32 @commute_subop0_zshiftc_oneuse(i32 %x, i32 %y, i32 %z) { } define i32 @commute_subop0_zshiftc(i32 %x, i32 %y, i32 %z) { -; CHECK-LABEL: commute_subop0_zshiftc: -; CHECK: // %bb.0: -; CHECK-NEXT: lsl w8, w2, #2 -; CHECK-NEXT: sub w9, w8, w1 -; CHECK-NEXT: add w9, w9, w0, lsl #3 -; CHECK-NEXT: eor w0, w8, w9 -; CHECK-NEXT: ret +; CHECK-SD-LABEL: commute_subop0_zshiftc: +; CHECK-SD: // %bb.0: +; CHECK-SD-NEXT: lsl w8, w2, #2 +; CHECK-SD-NEXT: sub w9, w8, w1 +; CHECK-SD-NEXT: add w9, w9, w0, lsl #3 +; CHECK-SD-NEXT: eor w0, w8, w9 +; CHECK-SD-NEXT: ret +; +; CHECK-GI-LABEL: commute_subop0_zshiftc: +; CHECK-GI: // %bb.0: +; CHECK-GI-NEXT: lsl w8, w0, #3 +; CHECK-GI-NEXT: lsl w9, w2, #2 +; CHECK-GI-NEXT: sub w8, w8, w1 +; CHECK-GI-NEXT: add w8, w8, w9 +; CHECK-GI-NEXT: eor w0, w9, w8 +; CHECK-GI-NEXT: ret %xshl = shl i32 %x, 3 %sub = sub i32 %xshl, %y %zshl = shl i32 %z, 2 |