diff options
Diffstat (limited to 'llvm/test/CodeGen/AArch64/midpoint-int.ll')
-rw-r--r-- | llvm/test/CodeGen/AArch64/midpoint-int.ll | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/AArch64/midpoint-int.ll b/llvm/test/CodeGen/AArch64/midpoint-int.ll new file mode 100644 index 00000000000..9b80866875d --- /dev/null +++ b/llvm/test/CodeGen/AArch64/midpoint-int.ll @@ -0,0 +1,535 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s + +; These test cases are inspired by C++2a std::midpoint(). +; See https://bugs.llvm.org/show_bug.cgi?id=40965 + +; ---------------------------------------------------------------------------- ; +; 32-bit width +; ---------------------------------------------------------------------------- ; + +; Values come from regs + +define i32 @scalar_i32_signed_reg_reg(i32 %a1, i32 %a2) nounwind { +; CHECK-LABEL: scalar_i32_signed_reg_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: cmp w0, w1 +; CHECK-NEXT: csel w9, w1, w0, gt +; CHECK-NEXT: csel w10, w0, w1, gt +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: sub w9, w10, w9 +; CHECK-NEXT: cneg w8, w8, le +; CHECK-NEXT: lsr w9, w9, #1 +; CHECK-NEXT: madd w0, w9, w8, w0 +; CHECK-NEXT: ret + %t3 = icmp sgt i32 %a1, %a2 ; signed + %t4 = select i1 %t3, i32 -1, i32 1 + %t5 = select i1 %t3, i32 %a2, i32 %a1 + %t6 = select i1 %t3, i32 %a1, i32 %a2 + %t7 = sub i32 %t6, %t5 + %t8 = lshr i32 %t7, 1 + %t9 = mul nsw i32 %t8, %t4 ; signed + %a10 = add nsw i32 %t9, %a1 ; signed + ret i32 %a10 +} + +define i32 @scalar_i32_unsigned_reg_reg(i32 %a1, i32 %a2) nounwind { +; CHECK-LABEL: scalar_i32_unsigned_reg_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: cmp w0, w1 +; CHECK-NEXT: csel w9, w1, w0, hi +; CHECK-NEXT: csel w10, w0, w1, hi +; CHECK-NEXT: mov w8, #-1 +; CHECK-NEXT: sub w9, w10, w9 +; CHECK-NEXT: cneg w8, w8, ls +; CHECK-NEXT: lsr w9, w9, #1 +; CHECK-NEXT: madd w0, w9, w8, w0 +; CHECK-NEXT: ret + %t3 = icmp ugt i32 %a1, %a2 + %t4 = select i1 %t3, i32 -1, i32 1 + %t5 = select i1 %t3, i32 %a2, i32 %a1 + %t6 = select i1 %t3, i32 %a1, i32 %a2 + %t7 = sub i32 %t6, %t5 + %t8 = lshr i32 %t7, 1 + %t9 = mul i32 %t8, %t4 + %a10 = add i32 %t9, %a1 + ret i32 %a10 +} + +; Values are loaded. Only check signed case. + +define i32 @scalar_i32_signed_mem_reg(i32* %a1_addr, i32 %a2) nounwind { +; CHECK-LABEL: scalar_i32_signed_mem_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: ldr w8, [x0] +; CHECK-NEXT: mov w9, #-1 +; CHECK-NEXT: cmp w8, w1 +; CHECK-NEXT: csel w10, w1, w8, gt +; CHECK-NEXT: csel w11, w8, w1, gt +; CHECK-NEXT: sub w10, w11, w10 +; CHECK-NEXT: cneg w9, w9, le +; CHECK-NEXT: lsr w10, w10, #1 +; CHECK-NEXT: madd w0, w10, w9, w8 +; CHECK-NEXT: ret + %a1 = load i32, i32* %a1_addr + %t3 = icmp sgt i32 %a1, %a2 ; signed + %t4 = select i1 %t3, i32 -1, i32 1 + %t5 = select i1 %t3, i32 %a2, i32 %a1 + %t6 = select i1 %t3, i32 %a1, i32 %a2 + %t7 = sub i32 %t6, %t5 + %t8 = lshr i32 %t7, 1 + %t9 = mul nsw i32 %t8, %t4 ; signed + %a10 = add nsw i32 %t9, %a1 ; signed + ret i32 %a10 +} + +define i32 @scalar_i32_signed_reg_mem(i32 %a1, i32* %a2_addr) nounwind { +; CHECK-LABEL: scalar_i32_signed_reg_mem: +; CHECK: // %bb.0: +; CHECK-NEXT: ldr w8, [x1] +; CHECK-NEXT: mov w9, #-1 +; CHECK-NEXT: cmp w0, w8 +; CHECK-NEXT: csel w10, w8, w0, gt +; CHECK-NEXT: csel w8, w0, w8, gt +; CHECK-NEXT: sub w8, w8, w10 +; CHECK-NEXT: cneg w9, w9, le +; CHECK-NEXT: lsr w8, w8, #1 +; CHECK-NEXT: madd w0, w8, w9, w0 +; CHECK-NEXT: ret + %a2 = load i32, i32* %a2_addr + %t3 = icmp sgt i32 %a1, %a2 ; signed + %t4 = select i1 %t3, i32 -1, i32 1 + %t5 = select i1 %t3, i32 %a2, i32 %a1 + %t6 = select i1 %t3, i32 %a1, i32 %a2 + %t7 = sub i32 %t6, %t5 + %t8 = lshr i32 %t7, 1 + %t9 = mul nsw i32 %t8, %t4 ; signed + %a10 = add nsw i32 %t9, %a1 ; signed + ret i32 %a10 +} + +define i32 @scalar_i32_signed_mem_mem(i32* %a1_addr, i32* %a2_addr) nounwind { +; CHECK-LABEL: scalar_i32_signed_mem_mem: +; CHECK: // %bb.0: +; CHECK-NEXT: ldr w8, [x0] +; CHECK-NEXT: ldr w9, [x1] +; CHECK-NEXT: mov w10, #-1 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w11, w9, w8, gt +; CHECK-NEXT: csel w9, w8, w9, gt +; CHECK-NEXT: sub w9, w9, w11 +; CHECK-NEXT: cneg w10, w10, le +; CHECK-NEXT: lsr w9, w9, #1 +; CHECK-NEXT: madd w0, w9, w10, w8 +; CHECK-NEXT: ret + %a1 = load i32, i32* %a1_addr + %a2 = load i32, i32* %a2_addr + %t3 = icmp sgt i32 %a1, %a2 ; signed + %t4 = select i1 %t3, i32 -1, i32 1 + %t5 = select i1 %t3, i32 %a2, i32 %a1 + %t6 = select i1 %t3, i32 %a1, i32 %a2 + %t7 = sub i32 %t6, %t5 + %t8 = lshr i32 %t7, 1 + %t9 = mul nsw i32 %t8, %t4 ; signed + %a10 = add nsw i32 %t9, %a1 ; signed + ret i32 %a10 +} + +; ---------------------------------------------------------------------------- ; +; 64-bit width +; ---------------------------------------------------------------------------- ; + +; Values come from regs + +define i64 @scalar_i64_signed_reg_reg(i64 %a1, i64 %a2) nounwind { +; CHECK-LABEL: scalar_i64_signed_reg_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: cmp x0, x1 +; CHECK-NEXT: csel x9, x1, x0, gt +; CHECK-NEXT: csel x10, x0, x1, gt +; CHECK-NEXT: mov x8, #-1 +; CHECK-NEXT: sub x9, x10, x9 +; CHECK-NEXT: cneg x8, x8, le +; CHECK-NEXT: lsr x9, x9, #1 +; CHECK-NEXT: madd x0, x9, x8, x0 +; CHECK-NEXT: ret + %t3 = icmp sgt i64 %a1, %a2 ; signed + %t4 = select i1 %t3, i64 -1, i64 1 + %t5 = select i1 %t3, i64 %a2, i64 %a1 + %t6 = select i1 %t3, i64 %a1, i64 %a2 + %t7 = sub i64 %t6, %t5 + %t8 = lshr i64 %t7, 1 + %t9 = mul nsw i64 %t8, %t4 ; signed + %a10 = add nsw i64 %t9, %a1 ; signed + ret i64 %a10 +} + +define i64 @scalar_i64_unsigned_reg_reg(i64 %a1, i64 %a2) nounwind { +; CHECK-LABEL: scalar_i64_unsigned_reg_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: cmp x0, x1 +; CHECK-NEXT: csel x9, x1, x0, hi +; CHECK-NEXT: csel x10, x0, x1, hi +; CHECK-NEXT: mov x8, #-1 +; CHECK-NEXT: sub x9, x10, x9 +; CHECK-NEXT: cneg x8, x8, ls +; CHECK-NEXT: lsr x9, x9, #1 +; CHECK-NEXT: madd x0, x9, x8, x0 +; CHECK-NEXT: ret + %t3 = icmp ugt i64 %a1, %a2 + %t4 = select i1 %t3, i64 -1, i64 1 + %t5 = select i1 %t3, i64 %a2, i64 %a1 + %t6 = select i1 %t3, i64 %a1, i64 %a2 + %t7 = sub i64 %t6, %t5 + %t8 = lshr i64 %t7, 1 + %t9 = mul i64 %t8, %t4 + %a10 = add i64 %t9, %a1 + ret i64 %a10 +} + +; Values are loaded. Only check signed case. + +define i64 @scalar_i64_signed_mem_reg(i64* %a1_addr, i64 %a2) nounwind { +; CHECK-LABEL: scalar_i64_signed_mem_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: ldr x8, [x0] +; CHECK-NEXT: mov x9, #-1 +; CHECK-NEXT: cmp x8, x1 +; CHECK-NEXT: csel x10, x1, x8, gt +; CHECK-NEXT: csel x11, x8, x1, gt +; CHECK-NEXT: sub x10, x11, x10 +; CHECK-NEXT: cneg x9, x9, le +; CHECK-NEXT: lsr x10, x10, #1 +; CHECK-NEXT: madd x0, x10, x9, x8 +; CHECK-NEXT: ret + %a1 = load i64, i64* %a1_addr + %t3 = icmp sgt i64 %a1, %a2 ; signed + %t4 = select i1 %t3, i64 -1, i64 1 + %t5 = select i1 %t3, i64 %a2, i64 %a1 + %t6 = select i1 %t3, i64 %a1, i64 %a2 + %t7 = sub i64 %t6, %t5 + %t8 = lshr i64 %t7, 1 + %t9 = mul nsw i64 %t8, %t4 ; signed + %a10 = add nsw i64 %t9, %a1 ; signed + ret i64 %a10 +} + +define i64 @scalar_i64_signed_reg_mem(i64 %a1, i64* %a2_addr) nounwind { +; CHECK-LABEL: scalar_i64_signed_reg_mem: +; CHECK: // %bb.0: +; CHECK-NEXT: ldr x8, [x1] +; CHECK-NEXT: mov x9, #-1 +; CHECK-NEXT: cmp x0, x8 +; CHECK-NEXT: csel x10, x8, x0, gt +; CHECK-NEXT: csel x8, x0, x8, gt +; CHECK-NEXT: sub x8, x8, x10 +; CHECK-NEXT: cneg x9, x9, le +; CHECK-NEXT: lsr x8, x8, #1 +; CHECK-NEXT: madd x0, x8, x9, x0 +; CHECK-NEXT: ret + %a2 = load i64, i64* %a2_addr + %t3 = icmp sgt i64 %a1, %a2 ; signed + %t4 = select i1 %t3, i64 -1, i64 1 + %t5 = select i1 %t3, i64 %a2, i64 %a1 + %t6 = select i1 %t3, i64 %a1, i64 %a2 + %t7 = sub i64 %t6, %t5 + %t8 = lshr i64 %t7, 1 + %t9 = mul nsw i64 %t8, %t4 ; signed + %a10 = add nsw i64 %t9, %a1 ; signed + ret i64 %a10 +} + +define i64 @scalar_i64_signed_mem_mem(i64* %a1_addr, i64* %a2_addr) nounwind { +; CHECK-LABEL: scalar_i64_signed_mem_mem: +; CHECK: // %bb.0: +; CHECK-NEXT: ldr x8, [x0] +; CHECK-NEXT: ldr x9, [x1] +; CHECK-NEXT: mov x10, #-1 +; CHECK-NEXT: cmp x8, x9 +; CHECK-NEXT: csel x11, x9, x8, gt +; CHECK-NEXT: csel x9, x8, x9, gt +; CHECK-NEXT: sub x9, x9, x11 +; CHECK-NEXT: cneg x10, x10, le +; CHECK-NEXT: lsr x9, x9, #1 +; CHECK-NEXT: madd x0, x9, x10, x8 +; CHECK-NEXT: ret + %a1 = load i64, i64* %a1_addr + %a2 = load i64, i64* %a2_addr + %t3 = icmp sgt i64 %a1, %a2 ; signed + %t4 = select i1 %t3, i64 -1, i64 1 + %t5 = select i1 %t3, i64 %a2, i64 %a1 + %t6 = select i1 %t3, i64 %a1, i64 %a2 + %t7 = sub i64 %t6, %t5 + %t8 = lshr i64 %t7, 1 + %t9 = mul nsw i64 %t8, %t4 ; signed + %a10 = add nsw i64 %t9, %a1 ; signed + ret i64 %a10 +} + +; ---------------------------------------------------------------------------- ; +; 16-bit width +; ---------------------------------------------------------------------------- ; + +; Values come from regs + +define i16 @scalar_i16_signed_reg_reg(i16 %a1, i16 %a2) nounwind { +; CHECK-LABEL: scalar_i16_signed_reg_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: sxth w8, w0 +; CHECK-NEXT: mov w9, #-1 +; CHECK-NEXT: cmp w8, w1, sxth +; CHECK-NEXT: cneg w8, w9, le +; CHECK-NEXT: csel w9, w1, w0, gt +; CHECK-NEXT: csel w10, w0, w1, gt +; CHECK-NEXT: sub w9, w10, w9 +; CHECK-NEXT: ubfx w9, w9, #1, #15 +; CHECK-NEXT: madd w0, w9, w8, w0 +; CHECK-NEXT: ret + %t3 = icmp sgt i16 %a1, %a2 ; signed + %t4 = select i1 %t3, i16 -1, i16 1 + %t5 = select i1 %t3, i16 %a2, i16 %a1 + %t6 = select i1 %t3, i16 %a1, i16 %a2 + %t7 = sub i16 %t6, %t5 + %t8 = lshr i16 %t7, 1 + %t9 = mul nsw i16 %t8, %t4 ; signed + %a10 = add nsw i16 %t9, %a1 ; signed + ret i16 %a10 +} + +define i16 @scalar_i16_unsigned_reg_reg(i16 %a1, i16 %a2) nounwind { +; CHECK-LABEL: scalar_i16_unsigned_reg_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: and w8, w0, #0xffff +; CHECK-NEXT: mov w9, #-1 +; CHECK-NEXT: cmp w8, w1, uxth +; CHECK-NEXT: cneg w8, w9, ls +; CHECK-NEXT: csel w9, w1, w0, hi +; CHECK-NEXT: csel w10, w0, w1, hi +; CHECK-NEXT: sub w9, w10, w9 +; CHECK-NEXT: ubfx w9, w9, #1, #15 +; CHECK-NEXT: madd w0, w9, w8, w0 +; CHECK-NEXT: ret + %t3 = icmp ugt i16 %a1, %a2 + %t4 = select i1 %t3, i16 -1, i16 1 + %t5 = select i1 %t3, i16 %a2, i16 %a1 + %t6 = select i1 %t3, i16 %a1, i16 %a2 + %t7 = sub i16 %t6, %t5 + %t8 = lshr i16 %t7, 1 + %t9 = mul i16 %t8, %t4 + %a10 = add i16 %t9, %a1 + ret i16 %a10 +} + +; Values are loaded. Only check signed case. + +define i16 @scalar_i16_signed_mem_reg(i16* %a1_addr, i16 %a2) nounwind { +; CHECK-LABEL: scalar_i16_signed_mem_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: ldrsh w8, [x0] +; CHECK-NEXT: mov w9, #-1 +; CHECK-NEXT: cmp w8, w1, sxth +; CHECK-NEXT: csel w10, w1, w8, gt +; CHECK-NEXT: csel w11, w8, w1, gt +; CHECK-NEXT: sub w10, w11, w10 +; CHECK-NEXT: cneg w9, w9, le +; CHECK-NEXT: ubfx w10, w10, #1, #15 +; CHECK-NEXT: madd w0, w10, w9, w8 +; CHECK-NEXT: ret + %a1 = load i16, i16* %a1_addr + %t3 = icmp sgt i16 %a1, %a2 ; signed + %t4 = select i1 %t3, i16 -1, i16 1 + %t5 = select i1 %t3, i16 %a2, i16 %a1 + %t6 = select i1 %t3, i16 %a1, i16 %a2 + %t7 = sub i16 %t6, %t5 + %t8 = lshr i16 %t7, 1 + %t9 = mul nsw i16 %t8, %t4 ; signed + %a10 = add nsw i16 %t9, %a1 ; signed + ret i16 %a10 +} + +define i16 @scalar_i16_signed_reg_mem(i16 %a1, i16* %a2_addr) nounwind { +; CHECK-LABEL: scalar_i16_signed_reg_mem: +; CHECK: // %bb.0: +; CHECK-NEXT: ldrsh w8, [x1] +; CHECK-NEXT: sxth w9, w0 +; CHECK-NEXT: mov w10, #-1 +; CHECK-NEXT: cmp w9, w8 +; CHECK-NEXT: cneg w9, w10, le +; CHECK-NEXT: csel w10, w8, w0, gt +; CHECK-NEXT: csel w8, w0, w8, gt +; CHECK-NEXT: sub w8, w8, w10 +; CHECK-NEXT: ubfx w8, w8, #1, #15 +; CHECK-NEXT: madd w0, w8, w9, w0 +; CHECK-NEXT: ret + %a2 = load i16, i16* %a2_addr + %t3 = icmp sgt i16 %a1, %a2 ; signed + %t4 = select i1 %t3, i16 -1, i16 1 + %t5 = select i1 %t3, i16 %a2, i16 %a1 + %t6 = select i1 %t3, i16 %a1, i16 %a2 + %t7 = sub i16 %t6, %t5 + %t8 = lshr i16 %t7, 1 + %t9 = mul nsw i16 %t8, %t4 ; signed + %a10 = add nsw i16 %t9, %a1 ; signed + ret i16 %a10 +} + +define i16 @scalar_i16_signed_mem_mem(i16* %a1_addr, i16* %a2_addr) nounwind { +; CHECK-LABEL: scalar_i16_signed_mem_mem: +; CHECK: // %bb.0: +; CHECK-NEXT: ldrsh w8, [x0] +; CHECK-NEXT: ldrsh w9, [x1] +; CHECK-NEXT: mov w10, #-1 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w11, w9, w8, gt +; CHECK-NEXT: csel w9, w8, w9, gt +; CHECK-NEXT: sub w9, w9, w11 +; CHECK-NEXT: cneg w10, w10, le +; CHECK-NEXT: ubfx w9, w9, #1, #15 +; CHECK-NEXT: madd w0, w9, w10, w8 +; CHECK-NEXT: ret + %a1 = load i16, i16* %a1_addr + %a2 = load i16, i16* %a2_addr + %t3 = icmp sgt i16 %a1, %a2 ; signed + %t4 = select i1 %t3, i16 -1, i16 1 + %t5 = select i1 %t3, i16 %a2, i16 %a1 + %t6 = select i1 %t3, i16 %a1, i16 %a2 + %t7 = sub i16 %t6, %t5 + %t8 = lshr i16 %t7, 1 + %t9 = mul nsw i16 %t8, %t4 ; signed + %a10 = add nsw i16 %t9, %a1 ; signed + ret i16 %a10 +} + +; ---------------------------------------------------------------------------- ; +; 8-bit width +; ---------------------------------------------------------------------------- ; + +; Values come from regs + +define i8 @scalar_i8_signed_reg_reg(i8 %a1, i8 %a2) nounwind { +; CHECK-LABEL: scalar_i8_signed_reg_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: sxtb w8, w0 +; CHECK-NEXT: mov w9, #-1 +; CHECK-NEXT: cmp w8, w1, sxtb +; CHECK-NEXT: cneg w8, w9, le +; CHECK-NEXT: csel w9, w1, w0, gt +; CHECK-NEXT: csel w10, w0, w1, gt +; CHECK-NEXT: sub w9, w10, w9 +; CHECK-NEXT: ubfx w9, w9, #1, #7 +; CHECK-NEXT: madd w0, w9, w8, w0 +; CHECK-NEXT: ret + %t3 = icmp sgt i8 %a1, %a2 ; signed + %t4 = select i1 %t3, i8 -1, i8 1 + %t5 = select i1 %t3, i8 %a2, i8 %a1 + %t6 = select i1 %t3, i8 %a1, i8 %a2 + %t7 = sub i8 %t6, %t5 + %t8 = lshr i8 %t7, 1 + %t9 = mul nsw i8 %t8, %t4 ; signed + %a10 = add nsw i8 %t9, %a1 ; signed + ret i8 %a10 +} + +define i8 @scalar_i8_unsigned_reg_reg(i8 %a1, i8 %a2) nounwind { +; CHECK-LABEL: scalar_i8_unsigned_reg_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: and w8, w0, #0xff +; CHECK-NEXT: mov w9, #-1 +; CHECK-NEXT: cmp w8, w1, uxtb +; CHECK-NEXT: cneg w8, w9, ls +; CHECK-NEXT: csel w9, w1, w0, hi +; CHECK-NEXT: csel w10, w0, w1, hi +; CHECK-NEXT: sub w9, w10, w9 +; CHECK-NEXT: ubfx w9, w9, #1, #7 +; CHECK-NEXT: madd w0, w9, w8, w0 +; CHECK-NEXT: ret + %t3 = icmp ugt i8 %a1, %a2 + %t4 = select i1 %t3, i8 -1, i8 1 + %t5 = select i1 %t3, i8 %a2, i8 %a1 + %t6 = select i1 %t3, i8 %a1, i8 %a2 + %t7 = sub i8 %t6, %t5 + %t8 = lshr i8 %t7, 1 + %t9 = mul i8 %t8, %t4 + %a10 = add i8 %t9, %a1 + ret i8 %a10 +} + +; Values are loaded. Only check signed case. + +define i8 @scalar_i8_signed_mem_reg(i8* %a1_addr, i8 %a2) nounwind { +; CHECK-LABEL: scalar_i8_signed_mem_reg: +; CHECK: // %bb.0: +; CHECK-NEXT: ldrsb w8, [x0] +; CHECK-NEXT: mov w9, #-1 +; CHECK-NEXT: cmp w8, w1, sxtb +; CHECK-NEXT: csel w10, w1, w8, gt +; CHECK-NEXT: csel w11, w8, w1, gt +; CHECK-NEXT: sub w10, w11, w10 +; CHECK-NEXT: cneg w9, w9, le +; CHECK-NEXT: ubfx w10, w10, #1, #7 +; CHECK-NEXT: madd w0, w10, w9, w8 +; CHECK-NEXT: ret + %a1 = load i8, i8* %a1_addr + %t3 = icmp sgt i8 %a1, %a2 ; signed + %t4 = select i1 %t3, i8 -1, i8 1 + %t5 = select i1 %t3, i8 %a2, i8 %a1 + %t6 = select i1 %t3, i8 %a1, i8 %a2 + %t7 = sub i8 %t6, %t5 + %t8 = lshr i8 %t7, 1 + %t9 = mul nsw i8 %t8, %t4 ; signed + %a10 = add nsw i8 %t9, %a1 ; signed + ret i8 %a10 +} + +define i8 @scalar_i8_signed_reg_mem(i8 %a1, i8* %a2_addr) nounwind { +; CHECK-LABEL: scalar_i8_signed_reg_mem: +; CHECK: // %bb.0: +; CHECK-NEXT: ldrsb w8, [x1] +; CHECK-NEXT: sxtb w9, w0 +; CHECK-NEXT: mov w10, #-1 +; CHECK-NEXT: cmp w9, w8 +; CHECK-NEXT: cneg w9, w10, le +; CHECK-NEXT: csel w10, w8, w0, gt +; CHECK-NEXT: csel w8, w0, w8, gt +; CHECK-NEXT: sub w8, w8, w10 +; CHECK-NEXT: ubfx w8, w8, #1, #7 +; CHECK-NEXT: madd w0, w8, w9, w0 +; CHECK-NEXT: ret + %a2 = load i8, i8* %a2_addr + %t3 = icmp sgt i8 %a1, %a2 ; signed + %t4 = select i1 %t3, i8 -1, i8 1 + %t5 = select i1 %t3, i8 %a2, i8 %a1 + %t6 = select i1 %t3, i8 %a1, i8 %a2 + %t7 = sub i8 %t6, %t5 + %t8 = lshr i8 %t7, 1 + %t9 = mul nsw i8 %t8, %t4 ; signed + %a10 = add nsw i8 %t9, %a1 ; signed + ret i8 %a10 +} + +define i8 @scalar_i8_signed_mem_mem(i8* %a1_addr, i8* %a2_addr) nounwind { +; CHECK-LABEL: scalar_i8_signed_mem_mem: +; CHECK: // %bb.0: +; CHECK-NEXT: ldrsb w8, [x0] +; CHECK-NEXT: ldrsb w9, [x1] +; CHECK-NEXT: mov w10, #-1 +; CHECK-NEXT: cmp w8, w9 +; CHECK-NEXT: csel w11, w9, w8, gt +; CHECK-NEXT: csel w9, w8, w9, gt +; CHECK-NEXT: sub w9, w9, w11 +; CHECK-NEXT: cneg w10, w10, le +; CHECK-NEXT: ubfx w9, w9, #1, #7 +; CHECK-NEXT: madd w0, w9, w10, w8 +; CHECK-NEXT: ret + %a1 = load i8, i8* %a1_addr + %a2 = load i8, i8* %a2_addr + %t3 = icmp sgt i8 %a1, %a2 ; signed + %t4 = select i1 %t3, i8 -1, i8 1 + %t5 = select i1 %t3, i8 %a2, i8 %a1 + %t6 = select i1 %t3, i8 %a1, i8 %a2 + %t7 = sub i8 %t6, %t5 + %t8 = lshr i8 %t7, 1 + %t9 = mul nsw i8 %t8, %t4 ; signed + %a10 = add nsw i8 %t9, %a1 ; signed + ret i8 %a10 +} |