| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc -verify-machineinstrs -mtriple=thumbv6m-none-eabi < %s | FileCheck %s --check-prefix=CHECKT1 |
| ; RUN: llc -verify-machineinstrs -mtriple=thumbv7m-none-eabi < %s | FileCheck %s --check-prefixes=CHECKT2 |
| ; RUN: llc -verify-machineinstrs -mtriple=thumbv8.1m.main-none-eabi < %s | FileCheck %s --check-prefixes=CHECKT2 |
| |
| declare i64 @llvm.abs.i64(i64, i1 immarg) |
| |
| define i64 @neg_abs64(i64 %x) { |
| ; CHECKT1-LABEL: neg_abs64: |
| ; CHECKT1: @ %bb.0: |
| ; CHECKT1-NEXT: asrs r2, r1, #31 |
| ; CHECKT1-NEXT: eors r1, r2 |
| ; CHECKT1-NEXT: eors r0, r2 |
| ; CHECKT1-NEXT: subs r0, r2, r0 |
| ; CHECKT1-NEXT: sbcs r2, r1 |
| ; CHECKT1-NEXT: mov r1, r2 |
| ; CHECKT1-NEXT: bx lr |
| ; |
| ; CHECKT2-LABEL: neg_abs64: |
| ; CHECKT2: @ %bb.0: |
| ; CHECKT2-NEXT: eor.w r0, r0, r1, asr #31 |
| ; CHECKT2-NEXT: eor.w r2, r1, r1, asr #31 |
| ; CHECKT2-NEXT: asrs r3, r1, #31 |
| ; CHECKT2-NEXT: rsbs r0, r0, r1, asr #31 |
| ; CHECKT2-NEXT: sbc.w r1, r3, r2 |
| ; CHECKT2-NEXT: bx lr |
| %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true) |
| %neg = sub nsw i64 0, %abs |
| ret i64 %neg |
| } |
| |
| declare i32 @llvm.abs.i32(i32, i1 immarg) |
| |
| define i32 @neg_abs32(i32 %x) { |
| ; CHECKT1-LABEL: neg_abs32: |
| ; CHECKT1: @ %bb.0: |
| ; CHECKT1-NEXT: asrs r1, r0, #31 |
| ; CHECKT1-NEXT: eors r0, r1 |
| ; CHECKT1-NEXT: subs r0, r1, r0 |
| ; CHECKT1-NEXT: bx lr |
| ; |
| ; CHECKT2-LABEL: neg_abs32: |
| ; CHECKT2: @ %bb.0: |
| ; CHECKT2-NEXT: eor.w r1, r0, r0, asr #31 |
| ; CHECKT2-NEXT: rsb r0, r1, r0, asr #31 |
| ; CHECKT2-NEXT: bx lr |
| %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true) |
| %neg = sub nsw i32 0, %abs |
| ret i32 %neg |
| } |
| |
| declare i16 @llvm.abs.i16(i16, i1 immarg) |
| |
| define i16 @neg_abs16(i16 %x) { |
| ; CHECKT1-LABEL: neg_abs16: |
| ; CHECKT1: @ %bb.0: |
| ; CHECKT1-NEXT: sxth r1, r0 |
| ; CHECKT1-NEXT: asrs r1, r1, #15 |
| ; CHECKT1-NEXT: eors r0, r1 |
| ; CHECKT1-NEXT: subs r0, r1, r0 |
| ; CHECKT1-NEXT: bx lr |
| ; |
| ; CHECKT2-LABEL: neg_abs16: |
| ; CHECKT2: @ %bb.0: |
| ; CHECKT2-NEXT: sxth r1, r0 |
| ; CHECKT2-NEXT: eor.w r0, r0, r1, asr #15 |
| ; CHECKT2-NEXT: rsb r0, r0, r1, asr #15 |
| ; CHECKT2-NEXT: bx lr |
| %abs = tail call i16 @llvm.abs.i16(i16 %x, i1 true) |
| %neg = sub nsw i16 0, %abs |
| ret i16 %neg |
| } |
| |
| |
| declare i128 @llvm.abs.i128(i128, i1 immarg) |
| |
| define i128 @neg_abs128(i128 %x) { |
| ; CHECKT1-LABEL: neg_abs128: |
| ; CHECKT1: @ %bb.0: |
| ; CHECKT1-NEXT: .save {r4, r5, r6, lr} |
| ; CHECKT1-NEXT: push {r4, r5, r6, lr} |
| ; CHECKT1-NEXT: asrs r4, r3, #31 |
| ; CHECKT1-NEXT: eors r3, r4 |
| ; CHECKT1-NEXT: eors r2, r4 |
| ; CHECKT1-NEXT: eors r1, r4 |
| ; CHECKT1-NEXT: eors r0, r4 |
| ; CHECKT1-NEXT: subs r0, r4, r0 |
| ; CHECKT1-NEXT: mov r5, r4 |
| ; CHECKT1-NEXT: sbcs r5, r1 |
| ; CHECKT1-NEXT: mov r6, r4 |
| ; CHECKT1-NEXT: sbcs r6, r2 |
| ; CHECKT1-NEXT: sbcs r4, r3 |
| ; CHECKT1-NEXT: mov r1, r5 |
| ; CHECKT1-NEXT: mov r2, r6 |
| ; CHECKT1-NEXT: mov r3, r4 |
| ; CHECKT1-NEXT: pop {r4, r5, r6, pc} |
| ; |
| ; CHECKT2-LABEL: neg_abs128: |
| ; CHECKT2: @ %bb.0: |
| ; CHECKT2-NEXT: .save {r7, lr} |
| ; CHECKT2-NEXT: push {r7, lr} |
| ; CHECKT2-NEXT: eor.w r0, r0, r3, asr #31 |
| ; CHECKT2-NEXT: eor.w r1, r1, r3, asr #31 |
| ; CHECKT2-NEXT: eor.w r2, r2, r3, asr #31 |
| ; CHECKT2-NEXT: asr.w lr, r3, #31 |
| ; CHECKT2-NEXT: rsbs r0, r0, r3, asr #31 |
| ; CHECKT2-NEXT: eor.w r12, r3, r3, asr #31 |
| ; CHECKT2-NEXT: sbcs.w r1, lr, r1 |
| ; CHECKT2-NEXT: sbcs.w r2, lr, r2 |
| ; CHECKT2-NEXT: sbc.w r3, lr, r12 |
| ; CHECKT2-NEXT: pop {r7, pc} |
| %abs = tail call i128 @llvm.abs.i128(i128 %x, i1 true) |
| %neg = sub nsw i128 0, %abs |
| ret i128 %neg |
| } |
| |
| |
| |
| define i64 @abs64(i64 %x) { |
| ; CHECKT1-LABEL: abs64: |
| ; CHECKT1: @ %bb.0: |
| ; CHECKT1-NEXT: asrs r2, r1, #31 |
| ; CHECKT1-NEXT: adds r0, r0, r2 |
| ; CHECKT1-NEXT: adcs r1, r2 |
| ; CHECKT1-NEXT: eors r0, r2 |
| ; CHECKT1-NEXT: eors r1, r2 |
| ; CHECKT1-NEXT: bx lr |
| ; |
| ; CHECKT2-LABEL: abs64: |
| ; CHECKT2: @ %bb.0: |
| ; CHECKT2-NEXT: adds.w r0, r0, r1, asr #31 |
| ; CHECKT2-NEXT: adc.w r2, r1, r1, asr #31 |
| ; CHECKT2-NEXT: eor.w r0, r0, r1, asr #31 |
| ; CHECKT2-NEXT: eor.w r1, r2, r1, asr #31 |
| ; CHECKT2-NEXT: bx lr |
| %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true) |
| ret i64 %abs |
| } |
| |
| define i32 @abs32(i32 %x) { |
| ; CHECKT1-LABEL: abs32: |
| ; CHECKT1: @ %bb.0: |
| ; CHECKT1-NEXT: asrs r1, r0, #31 |
| ; CHECKT1-NEXT: adds r0, r0, r1 |
| ; CHECKT1-NEXT: eors r0, r1 |
| ; CHECKT1-NEXT: bx lr |
| ; |
| ; CHECKT2-LABEL: abs32: |
| ; CHECKT2: @ %bb.0: |
| ; CHECKT2-NEXT: cmp r0, #0 |
| ; CHECKT2-NEXT: it mi |
| ; CHECKT2-NEXT: rsbmi r0, r0, #0 |
| ; CHECKT2-NEXT: bx lr |
| %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true) |
| ret i32 %abs |
| } |
| |
| define i16 @abs16(i16 %x) { |
| ; CHECKT1-LABEL: abs16: |
| ; CHECKT1: @ %bb.0: |
| ; CHECKT1-NEXT: sxth r1, r0 |
| ; CHECKT1-NEXT: asrs r1, r1, #15 |
| ; CHECKT1-NEXT: adds r0, r0, r1 |
| ; CHECKT1-NEXT: eors r0, r1 |
| ; CHECKT1-NEXT: bx lr |
| ; |
| ; CHECKT2-LABEL: abs16: |
| ; CHECKT2: @ %bb.0: |
| ; CHECKT2-NEXT: sxth r1, r0 |
| ; CHECKT2-NEXT: add.w r0, r0, r1, asr #15 |
| ; CHECKT2-NEXT: eor.w r0, r0, r1, asr #15 |
| ; CHECKT2-NEXT: bx lr |
| %abs = tail call i16 @llvm.abs.i16(i16 %x, i1 true) |
| ret i16 %abs |
| } |
| |
| define i128 @abs128(i128 %x) { |
| ; CHECKT1-LABEL: abs128: |
| ; CHECKT1: @ %bb.0: |
| ; CHECKT1-NEXT: .save {r4, lr} |
| ; CHECKT1-NEXT: push {r4, lr} |
| ; CHECKT1-NEXT: asrs r4, r3, #31 |
| ; CHECKT1-NEXT: adds r0, r0, r4 |
| ; CHECKT1-NEXT: adcs r1, r4 |
| ; CHECKT1-NEXT: adcs r2, r4 |
| ; CHECKT1-NEXT: adcs r3, r4 |
| ; CHECKT1-NEXT: eors r0, r4 |
| ; CHECKT1-NEXT: eors r1, r4 |
| ; CHECKT1-NEXT: eors r2, r4 |
| ; CHECKT1-NEXT: eors r3, r4 |
| ; CHECKT1-NEXT: pop {r4, pc} |
| ; |
| ; CHECKT2-LABEL: abs128: |
| ; CHECKT2: @ %bb.0: |
| ; CHECKT2-NEXT: adds.w r0, r0, r3, asr #31 |
| ; CHECKT2-NEXT: adcs.w r1, r1, r3, asr #31 |
| ; CHECKT2-NEXT: eor.w r0, r0, r3, asr #31 |
| ; CHECKT2-NEXT: adcs.w r2, r2, r3, asr #31 |
| ; CHECKT2-NEXT: eor.w r1, r1, r3, asr #31 |
| ; CHECKT2-NEXT: adc.w r12, r3, r3, asr #31 |
| ; CHECKT2-NEXT: eor.w r2, r2, r3, asr #31 |
| ; CHECKT2-NEXT: eor.w r3, r12, r3, asr #31 |
| ; CHECKT2-NEXT: bx lr |
| %abs = tail call i128 @llvm.abs.i128(i128 %x, i1 true) |
| ret i128 %abs |
| } |
| |