[llvm] [ARM] Enable creation of ARMISD::CMN nodes (PR #163223)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 23 10:33:02 PDT 2025
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/163223
>From 99eb567dc0dde98b62234d14350d356f84fda016 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 13 Oct 2025 13:51:16 -0400
Subject: [PATCH 1/2] Pre-commit test (NFC)
---
llvm/test/CodeGen/ARM/cmp-to-cmn.ll | 2200 +++++++++++++++++++++++++++
1 file changed, 2200 insertions(+)
create mode 100644 llvm/test/CodeGen/ARM/cmp-to-cmn.ll
diff --git a/llvm/test/CodeGen/ARM/cmp-to-cmn.ll b/llvm/test/CodeGen/ARM/cmp-to-cmn.ll
new file mode 100644
index 0000000000000..12659a55bfc4b
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/cmp-to-cmn.ll
@@ -0,0 +1,2200 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=armv7 %s -o - | FileCheck %s --check-prefixes=CHECK-ARM
+; RUN: llc -mtriple=thumb-eabi -mcpu=arm7tdmi %s -o - | FileCheck %s --check-prefix=CHECK-T1
+; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck %s --check-prefix=CHECK-T2
+
+define i1 @test_EQ_IllEbT(i64 %a, i64 %b) {
+; CHECK-ARM-LABEL: test_EQ_IllEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r2, r2, #0
+; CHECK-ARM-NEXT: eor r0, r2, r0
+; CHECK-ARM-NEXT: rsc r2, r3, #0
+; CHECK-ARM-NEXT: eor r1, r2, r1
+; CHECK-ARM-NEXT: orr r0, r0, r1
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IllEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: .save {r4, lr}
+; CHECK-T1-NEXT: push {r4, lr}
+; CHECK-T1-NEXT: movs r4, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: sbcs r4, r3
+; CHECK-T1-NEXT: eors r4, r1
+; CHECK-T1-NEXT: eors r0, r2
+; CHECK-T1-NEXT: orrs r0, r4
+; CHECK-T1-NEXT: rsbs r1, r0, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: pop {r4}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+;
+; CHECK-T2-LABEL: test_EQ_IllEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: mov.w r12, #0
+; CHECK-T2-NEXT: sbc.w r3, r12, r3
+; CHECK-T2-NEXT: eors r1, r3
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %add = sub i64 0, %b
+ %cmp = icmp eq i64 %add, %a
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IliEbT(i64 %a, i32 %b) {
+; CHECK-ARM-LABEL: test_EQ_IliEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r0, r0, #0
+; CHECK-ARM-NEXT: rsc r1, r1, #0
+; CHECK-ARM-NEXT: eor r0, r2, r0
+; CHECK-ARM-NEXT: eor r1, r1, r2, asr #31
+; CHECK-ARM-NEXT: orr r0, r0, r1
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IliEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: .save {r4, lr}
+; CHECK-T1-NEXT: push {r4, lr}
+; CHECK-T1-NEXT: movs r3, #0
+; CHECK-T1-NEXT: rsbs r4, r0, #0
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: asrs r0, r2, #31
+; CHECK-T1-NEXT: eors r0, r3
+; CHECK-T1-NEXT: eors r4, r2
+; CHECK-T1-NEXT: orrs r4, r0
+; CHECK-T1-NEXT: rsbs r0, r4, #0
+; CHECK-T1-NEXT: adcs r0, r4
+; CHECK-T1-NEXT: pop {r4}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+;
+; CHECK-T2-LABEL: test_EQ_IliEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: rsbs r0, r0, #0
+; CHECK-T2-NEXT: mov.w r3, #0
+; CHECK-T2-NEXT: sbc.w r1, r3, r1
+; CHECK-T2-NEXT: eor.w r1, r1, r2, asr #31
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i32 %b to i64
+ %add = sub i64 0, %a
+ %cmp = icmp eq i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IlsEbT(i64 %a, i16 %b) {
+; CHECK-ARM-LABEL: test_EQ_IlsEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r0, r0, #0
+; CHECK-ARM-NEXT: sxth r2, r2
+; CHECK-ARM-NEXT: rsc r1, r1, #0
+; CHECK-ARM-NEXT: eor r0, r2, r0
+; CHECK-ARM-NEXT: eor r1, r1, r2, asr #31
+; CHECK-ARM-NEXT: orr r0, r0, r1
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IlsEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r3, #0
+; CHECK-T1-NEXT: rsbs r0, r0, #0
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: lsls r1, r2, #16
+; CHECK-T1-NEXT: asrs r2, r1, #31
+; CHECK-T1-NEXT: eors r2, r3
+; CHECK-T1-NEXT: asrs r1, r1, #16
+; CHECK-T1-NEXT: eors r1, r0
+; CHECK-T1-NEXT: orrs r1, r2
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IlsEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r3, #0
+; CHECK-T2-NEXT: rsbs r0, r0, #0
+; CHECK-T2-NEXT: sxth r2, r2
+; CHECK-T2-NEXT: sbc.w r1, r3, r1
+; CHECK-T2-NEXT: eor.w r1, r1, r2, asr #31
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %b to i64
+ %add = sub i64 0, %a
+ %cmp = icmp eq i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IlcEbT(i64 %a, i8 %b) {
+; CHECK-ARM-LABEL: test_EQ_IlcEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r0, r0, #0
+; CHECK-ARM-NEXT: uxtb r2, r2
+; CHECK-ARM-NEXT: rsc r1, r1, #0
+; CHECK-ARM-NEXT: eor r0, r2, r0
+; CHECK-ARM-NEXT: orr r0, r0, r1
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IlcEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r3, #0
+; CHECK-T1-NEXT: rsbs r0, r0, #0
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: movs r1, #255
+; CHECK-T1-NEXT: ands r1, r2
+; CHECK-T1-NEXT: eors r1, r0
+; CHECK-T1-NEXT: orrs r1, r3
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IlcEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r3, #0
+; CHECK-T2-NEXT: rsbs r0, r0, #0
+; CHECK-T2-NEXT: uxtb r2, r2
+; CHECK-T2-NEXT: sbc.w r1, r3, r1
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %b to i64
+ %add = sub i64 0, %a
+ %cmp = icmp eq i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IilEbT(i32 %a, i64 %b) {
+; CHECK-ARM-LABEL: test_EQ_IilEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r1, r2, #0
+; CHECK-ARM-NEXT: rsc r2, r3, #0
+; CHECK-ARM-NEXT: eor r1, r0, r1
+; CHECK-ARM-NEXT: eor r0, r2, r0, asr #31
+; CHECK-ARM-NEXT: orr r0, r1, r0
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IilEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r1, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: sbcs r1, r3
+; CHECK-T1-NEXT: asrs r3, r0, #31
+; CHECK-T1-NEXT: eors r3, r1
+; CHECK-T1-NEXT: eors r0, r2
+; CHECK-T1-NEXT: orrs r0, r3
+; CHECK-T1-NEXT: rsbs r1, r0, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IilEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: sbcs r1, r3
+; CHECK-T2-NEXT: eor.w r1, r1, r0, asr #31
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i32 %a to i64
+ %add = sub i64 0, %b
+ %cmp = icmp eq i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IiiEbT(i32 %a, i32 %b) {
+; CHECK-ARM-LABEL: test_EQ_IiiEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: add r0, r1, r0
+; CHECK-ARM-NEXT: rsb r0, r0, #0
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IiiEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: adds r0, r1, r0
+; CHECK-T1-NEXT: rsbs r1, r0, #0
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IiiEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: add r0, r1
+; CHECK-T2-NEXT: rsbs r0, r0, #0
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %add = sub i32 0, %b
+ %cmp = icmp eq i32 %add, %a
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IisEbT(i32 %a, i16 %b) {
+; CHECK-ARM-LABEL: test_EQ_IisEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: sxtah r0, r0, r1
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IisEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: lsls r1, r1, #16
+; CHECK-T1-NEXT: asrs r1, r1, #16
+; CHECK-T1-NEXT: adds r0, r0, r1
+; CHECK-T1-NEXT: rsbs r1, r0, #0
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IisEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: sxtah r0, r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %b to i32
+ %add = sub i32 0, %a
+ %cmp = icmp eq i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IicEbT(i32 %a, i8 %b) {
+; CHECK-ARM-LABEL: test_EQ_IicEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: uxtab r0, r0, r1
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IicEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r2, r1
+; CHECK-T1-NEXT: adds r1, r2, r0
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IicEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: uxtab r0, r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %b to i32
+ %add = sub i32 0, %a
+ %cmp = icmp eq i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IslEbT(i16 %a, i64 %b) {
+; CHECK-ARM-LABEL: test_EQ_IslEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r1, r2, #0
+; CHECK-ARM-NEXT: sxth r0, r0
+; CHECK-ARM-NEXT: rsc r2, r3, #0
+; CHECK-ARM-NEXT: eor r1, r0, r1
+; CHECK-ARM-NEXT: eor r0, r2, r0, asr #31
+; CHECK-ARM-NEXT: orr r0, r1, r0
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IslEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r1, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: sbcs r1, r3
+; CHECK-T1-NEXT: lsls r0, r0, #16
+; CHECK-T1-NEXT: asrs r3, r0, #31
+; CHECK-T1-NEXT: eors r3, r1
+; CHECK-T1-NEXT: asrs r1, r0, #16
+; CHECK-T1-NEXT: eors r1, r2
+; CHECK-T1-NEXT: orrs r1, r3
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IslEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: sbcs r1, r3
+; CHECK-T2-NEXT: sxth r0, r0
+; CHECK-T2-NEXT: eor.w r1, r1, r0, asr #31
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %a to i64
+ %add = sub i64 0, %b
+ %cmp = icmp eq i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IsiEbT(i16 %a, i32 %b) {
+; CHECK-ARM-LABEL: test_EQ_IsiEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: sxtah r0, r1, r0
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IsiEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: lsls r0, r0, #16
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: adds r0, r1, r0
+; CHECK-T1-NEXT: rsbs r1, r0, #0
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IsiEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: sxtah r0, r1, r0
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %a to i32
+ %add = sub i32 0, %b
+ %cmp = icmp eq i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IssEbT(i16 %a, i16 %b) {
+; CHECK-ARM-LABEL: test_EQ_IssEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: sxth r0, r0
+; CHECK-ARM-NEXT: sxtah r0, r0, r1
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IssEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: lsls r0, r0, #16
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: lsls r1, r1, #16
+; CHECK-T1-NEXT: asrs r1, r1, #16
+; CHECK-T1-NEXT: adds r0, r1, r0
+; CHECK-T1-NEXT: rsbs r1, r0, #0
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IssEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: sxth r0, r0
+; CHECK-T2-NEXT: sxtah r0, r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %a to i32
+ %conv1 = sext i16 %b to i32
+ %add = sub nsw i32 0, %conv1
+ %cmp = icmp eq i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IscEbT(i16 %a, i8 %b) {
+; CHECK-ARM-LABEL: test_EQ_IscEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: sxth r0, r0
+; CHECK-ARM-NEXT: uxtab r0, r0, r1
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IscEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r2, r1
+; CHECK-T1-NEXT: lsls r0, r0, #16
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: adds r0, r2, r0
+; CHECK-T1-NEXT: rsbs r1, r0, #0
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IscEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: sxth r0, r0
+; CHECK-T2-NEXT: uxtab r0, r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %a to i32
+ %conv1 = zext i8 %b to i32
+ %add = sub nsw i32 0, %conv1
+ %cmp = icmp eq i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IclEbT(i8 %a, i64 %b) {
+; CHECK-ARM-LABEL: test_EQ_IclEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r1, r2, #0
+; CHECK-ARM-NEXT: uxtb r0, r0
+; CHECK-ARM-NEXT: rsc r2, r3, #0
+; CHECK-ARM-NEXT: eor r0, r0, r1
+; CHECK-ARM-NEXT: orr r0, r0, r2
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IclEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r1, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: sbcs r1, r3
+; CHECK-T1-NEXT: movs r3, #255
+; CHECK-T1-NEXT: ands r0, r3
+; CHECK-T1-NEXT: eors r0, r2
+; CHECK-T1-NEXT: orrs r0, r1
+; CHECK-T1-NEXT: rsbs r1, r0, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IclEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: uxtb r0, r0
+; CHECK-T2-NEXT: sbcs r1, r3
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %a to i64
+ %add = sub i64 0, %b
+ %cmp = icmp eq i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IciEbT(i8 %a, i32 %b) {
+; CHECK-ARM-LABEL: test_EQ_IciEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: uxtab r0, r1, r0
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IciEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r2, r0
+; CHECK-T1-NEXT: adds r1, r2, r1
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IciEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: uxtab r0, r1, r0
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %a to i32
+ %add = sub i32 0, %b
+ %cmp = icmp eq i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IcsEbT(i8 %a, i16 %b) {
+; CHECK-ARM-LABEL: test_EQ_IcsEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: sxth r1, r1
+; CHECK-ARM-NEXT: uxtab r0, r1, r0
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IcsEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r2, r0
+; CHECK-T1-NEXT: lsls r0, r1, #16
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: adds r1, r2, r0
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IcsEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: sxth r1, r1
+; CHECK-T2-NEXT: uxtab r0, r1, r0
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %a to i32
+ %conv1 = sext i16 %b to i32
+ %add = sub nsw i32 0, %conv1
+ %cmp = icmp eq i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_EQ_IccEbT(i8 %a, i8 %b) {
+; CHECK-ARM-LABEL: test_EQ_IccEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: uxtb r0, r0
+; CHECK-ARM-NEXT: uxtab r0, r0, r1
+; CHECK-ARM-NEXT: clz r0, r0
+; CHECK-ARM-NEXT: lsr r0, r0, #5
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_EQ_IccEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r1, r2
+; CHECK-T1-NEXT: ands r0, r2
+; CHECK-T1-NEXT: adds r1, r0, r1
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: adcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_EQ_IccEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: uxtb r0, r0
+; CHECK-T2-NEXT: uxtab r0, r0, r1
+; CHECK-T2-NEXT: clz r0, r0
+; CHECK-T2-NEXT: lsrs r0, r0, #5
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %a to i32
+ %conv1 = zext i8 %b to i32
+ %add = sub nsw i32 0, %conv1
+ %cmp = icmp eq i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IllEbT(i64 %a, i64 %b) {
+; CHECK-ARM-LABEL: test_NE_IllEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r2, r2, #0
+; CHECK-ARM-NEXT: eor r0, r2, r0
+; CHECK-ARM-NEXT: rsc r2, r3, #0
+; CHECK-ARM-NEXT: eor r1, r2, r1
+; CHECK-ARM-NEXT: orrs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IllEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: .save {r4, lr}
+; CHECK-T1-NEXT: push {r4, lr}
+; CHECK-T1-NEXT: movs r4, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: sbcs r4, r3
+; CHECK-T1-NEXT: eors r4, r1
+; CHECK-T1-NEXT: eors r0, r2
+; CHECK-T1-NEXT: orrs r0, r4
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: pop {r4}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+;
+; CHECK-T2-LABEL: test_NE_IllEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: mov.w r12, #0
+; CHECK-T2-NEXT: sbc.w r3, r12, r3
+; CHECK-T2-NEXT: eors r1, r3
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %add = sub i64 0, %b
+ %cmp = icmp ne i64 %add, %a
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IliEbT(i64 %a, i32 %b) {
+; CHECK-ARM-LABEL: test_NE_IliEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r0, r0, #0
+; CHECK-ARM-NEXT: rsc r1, r1, #0
+; CHECK-ARM-NEXT: eor r0, r2, r0
+; CHECK-ARM-NEXT: eor r1, r1, r2, asr #31
+; CHECK-ARM-NEXT: orrs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IliEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r3, #0
+; CHECK-T1-NEXT: rsbs r0, r0, #0
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: asrs r1, r2, #31
+; CHECK-T1-NEXT: eors r1, r3
+; CHECK-T1-NEXT: eors r0, r2
+; CHECK-T1-NEXT: orrs r0, r1
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IliEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: rsbs r0, r0, #0
+; CHECK-T2-NEXT: mov.w r3, #0
+; CHECK-T2-NEXT: sbc.w r1, r3, r1
+; CHECK-T2-NEXT: eor.w r1, r1, r2, asr #31
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i32 %b to i64
+ %add = sub i64 0, %a
+ %cmp = icmp ne i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IlsEbT(i64 %a, i16 %b) {
+; CHECK-ARM-LABEL: test_NE_IlsEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r0, r0, #0
+; CHECK-ARM-NEXT: sxth r2, r2
+; CHECK-ARM-NEXT: rsc r1, r1, #0
+; CHECK-ARM-NEXT: eor r0, r2, r0
+; CHECK-ARM-NEXT: eor r1, r1, r2, asr #31
+; CHECK-ARM-NEXT: orrs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IlsEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: .save {r4, lr}
+; CHECK-T1-NEXT: push {r4, lr}
+; CHECK-T1-NEXT: movs r3, #0
+; CHECK-T1-NEXT: rsbs r4, r0, #0
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: lsls r0, r2, #16
+; CHECK-T1-NEXT: asrs r1, r0, #31
+; CHECK-T1-NEXT: eors r1, r3
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: eors r0, r4
+; CHECK-T1-NEXT: orrs r0, r1
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: pop {r4}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+;
+; CHECK-T2-LABEL: test_NE_IlsEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r3, #0
+; CHECK-T2-NEXT: rsbs r0, r0, #0
+; CHECK-T2-NEXT: sxth r2, r2
+; CHECK-T2-NEXT: sbc.w r1, r3, r1
+; CHECK-T2-NEXT: eor.w r1, r1, r2, asr #31
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %b to i64
+ %add = sub i64 0, %a
+ %cmp = icmp ne i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IlcEbT(i64 %a, i8 %b) {
+; CHECK-ARM-LABEL: test_NE_IlcEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r0, r0, #0
+; CHECK-ARM-NEXT: uxtb r2, r2
+; CHECK-ARM-NEXT: rsc r1, r1, #0
+; CHECK-ARM-NEXT: eor r0, r2, r0
+; CHECK-ARM-NEXT: orrs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IlcEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: .save {r4, lr}
+; CHECK-T1-NEXT: push {r4, lr}
+; CHECK-T1-NEXT: movs r3, #0
+; CHECK-T1-NEXT: rsbs r4, r0, #0
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: movs r0, #255
+; CHECK-T1-NEXT: ands r0, r2
+; CHECK-T1-NEXT: eors r0, r4
+; CHECK-T1-NEXT: orrs r0, r3
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: pop {r4}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+;
+; CHECK-T2-LABEL: test_NE_IlcEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r3, #0
+; CHECK-T2-NEXT: rsbs r0, r0, #0
+; CHECK-T2-NEXT: uxtb r2, r2
+; CHECK-T2-NEXT: sbc.w r1, r3, r1
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %b to i64
+ %add = sub i64 0, %a
+ %cmp = icmp ne i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IilEbT(i32 %a, i64 %b) {
+; CHECK-ARM-LABEL: test_NE_IilEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r1, r2, #0
+; CHECK-ARM-NEXT: rsc r2, r3, #0
+; CHECK-ARM-NEXT: eor r1, r0, r1
+; CHECK-ARM-NEXT: eor r0, r2, r0, asr #31
+; CHECK-ARM-NEXT: orrs r0, r1, r0
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IilEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r1, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: sbcs r1, r3
+; CHECK-T1-NEXT: asrs r3, r0, #31
+; CHECK-T1-NEXT: eors r3, r1
+; CHECK-T1-NEXT: eors r0, r2
+; CHECK-T1-NEXT: orrs r0, r3
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IilEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: sbcs r1, r3
+; CHECK-T2-NEXT: eor.w r1, r1, r0, asr #31
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i32 %a to i64
+ %add = sub i64 0, %b
+ %cmp = icmp ne i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IiiEbT(i32 %a, i32 %b) {
+; CHECK-ARM-LABEL: test_NE_IiiEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsb r1, r1, #0
+; CHECK-ARM-NEXT: subs r0, r1, r0
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IiiEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: rsbs r1, r1, #0
+; CHECK-T1-NEXT: subs r0, r1, r0
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IiiEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: rsbs r1, r1, #0
+; CHECK-T2-NEXT: subs r0, r1, r0
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %add = sub i32 0, %b
+ %cmp = icmp ne i32 %add, %a
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IisEbT(i32 %a, i16 %b) {
+; CHECK-ARM-LABEL: test_NE_IisEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsb r0, r0, #0
+; CHECK-ARM-NEXT: sxth r1, r1
+; CHECK-ARM-NEXT: subs r0, r1, r0
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IisEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: rsbs r0, r0, #0
+; CHECK-T1-NEXT: lsls r1, r1, #16
+; CHECK-T1-NEXT: asrs r1, r1, #16
+; CHECK-T1-NEXT: subs r0, r0, r1
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IisEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: rsbs r0, r0, #0
+; CHECK-T2-NEXT: sxth r1, r1
+; CHECK-T2-NEXT: subs r0, r1, r0
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %b to i32
+ %add = sub i32 0, %a
+ %cmp = icmp ne i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IicEbT(i32 %a, i8 %b) {
+; CHECK-ARM-LABEL: test_NE_IicEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsb r0, r0, #0
+; CHECK-ARM-NEXT: uxtb r1, r1
+; CHECK-ARM-NEXT: subs r0, r1, r0
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IicEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r2, r1
+; CHECK-T1-NEXT: rsbs r0, r0, #0
+; CHECK-T1-NEXT: subs r0, r2, r0
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IicEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: rsbs r0, r0, #0
+; CHECK-T2-NEXT: uxtb r1, r1
+; CHECK-T2-NEXT: subs r0, r1, r0
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %b to i32
+ %add = sub i32 0, %a
+ %cmp = icmp ne i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IslEbT(i16 %a, i64 %b) {
+; CHECK-ARM-LABEL: test_NE_IslEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r1, r2, #0
+; CHECK-ARM-NEXT: sxth r0, r0
+; CHECK-ARM-NEXT: rsc r2, r3, #0
+; CHECK-ARM-NEXT: eor r1, r0, r1
+; CHECK-ARM-NEXT: eor r0, r2, r0, asr #31
+; CHECK-ARM-NEXT: orrs r0, r1, r0
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IslEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r1, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: sbcs r1, r3
+; CHECK-T1-NEXT: lsls r0, r0, #16
+; CHECK-T1-NEXT: asrs r3, r0, #31
+; CHECK-T1-NEXT: eors r3, r1
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: eors r0, r2
+; CHECK-T1-NEXT: orrs r0, r3
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IslEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: sbcs r1, r3
+; CHECK-T2-NEXT: sxth r0, r0
+; CHECK-T2-NEXT: eor.w r1, r1, r0, asr #31
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %a to i64
+ %add = sub i64 0, %b
+ %cmp = icmp ne i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IsiEbT(i16 %a, i32 %b) {
+; CHECK-ARM-LABEL: test_NE_IsiEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsb r1, r1, #0
+; CHECK-ARM-NEXT: sxth r0, r0
+; CHECK-ARM-NEXT: subs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IsiEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: rsbs r1, r1, #0
+; CHECK-T1-NEXT: lsls r0, r0, #16
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: subs r0, r1, r0
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IsiEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: rsbs r1, r1, #0
+; CHECK-T2-NEXT: sxth r0, r0
+; CHECK-T2-NEXT: subs r0, r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %a to i32
+ %add = sub i32 0, %b
+ %cmp = icmp ne i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IssEbT(i16 %a, i16 %b) {
+; CHECK-ARM-LABEL: test_NE_IssEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: sxth r1, r1
+; CHECK-ARM-NEXT: sxth r0, r0
+; CHECK-ARM-NEXT: rsb r1, r1, #0
+; CHECK-ARM-NEXT: subs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IssEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: lsls r0, r0, #16
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: lsls r1, r1, #16
+; CHECK-T1-NEXT: asrs r1, r1, #16
+; CHECK-T1-NEXT: rsbs r1, r1, #0
+; CHECK-T1-NEXT: subs r0, r1, r0
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IssEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: sxth r1, r1
+; CHECK-T2-NEXT: sxth r0, r0
+; CHECK-T2-NEXT: rsbs r1, r1, #0
+; CHECK-T2-NEXT: subs r0, r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %a to i32
+ %conv1 = sext i16 %b to i32
+ %add = sub nsw i32 0, %conv1
+ %cmp = icmp ne i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IscEbT(i16 %a, i8 %b) {
+; CHECK-ARM-LABEL: test_NE_IscEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: uxtb r1, r1
+; CHECK-ARM-NEXT: sxth r0, r0
+; CHECK-ARM-NEXT: rsb r1, r1, #0
+; CHECK-ARM-NEXT: subs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IscEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r2, r1
+; CHECK-T1-NEXT: rsbs r1, r2, #0
+; CHECK-T1-NEXT: lsls r0, r0, #16
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: subs r0, r1, r0
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IscEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: uxtb r1, r1
+; CHECK-T2-NEXT: sxth r0, r0
+; CHECK-T2-NEXT: rsbs r1, r1, #0
+; CHECK-T2-NEXT: subs r0, r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = sext i16 %a to i32
+ %conv1 = zext i8 %b to i32
+ %add = sub nsw i32 0, %conv1
+ %cmp = icmp ne i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IclEbT(i8 %a, i64 %b) {
+; CHECK-ARM-LABEL: test_NE_IclEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsbs r1, r2, #0
+; CHECK-ARM-NEXT: uxtb r0, r0
+; CHECK-ARM-NEXT: rsc r2, r3, #0
+; CHECK-ARM-NEXT: eor r0, r0, r1
+; CHECK-ARM-NEXT: orrs r0, r0, r2
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IclEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r1, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: sbcs r1, r3
+; CHECK-T1-NEXT: movs r3, #255
+; CHECK-T1-NEXT: ands r0, r3
+; CHECK-T1-NEXT: eors r0, r2
+; CHECK-T1-NEXT: orrs r0, r1
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IclEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: uxtb r0, r0
+; CHECK-T2-NEXT: sbcs r1, r3
+; CHECK-T2-NEXT: eors r0, r2
+; CHECK-T2-NEXT: orrs r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %a to i64
+ %add = sub i64 0, %b
+ %cmp = icmp ne i64 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IciEbT(i8 %a, i32 %b) {
+; CHECK-ARM-LABEL: test_NE_IciEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: rsb r1, r1, #0
+; CHECK-ARM-NEXT: uxtb r0, r0
+; CHECK-ARM-NEXT: subs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IciEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r2, r0
+; CHECK-T1-NEXT: rsbs r0, r1, #0
+; CHECK-T1-NEXT: subs r0, r2, r0
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IciEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: rsbs r1, r1, #0
+; CHECK-T2-NEXT: uxtb r0, r0
+; CHECK-T2-NEXT: subs r0, r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %a to i32
+ %add = sub i32 0, %b
+ %cmp = icmp ne i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IcsEbT(i8 %a, i16 %b) {
+; CHECK-ARM-LABEL: test_NE_IcsEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: sxth r1, r1
+; CHECK-ARM-NEXT: uxtb r0, r0
+; CHECK-ARM-NEXT: rsb r1, r1, #0
+; CHECK-ARM-NEXT: subs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IcsEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r2, r0
+; CHECK-T1-NEXT: lsls r0, r1, #16
+; CHECK-T1-NEXT: asrs r0, r0, #16
+; CHECK-T1-NEXT: rsbs r0, r0, #0
+; CHECK-T1-NEXT: subs r0, r2, r0
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IcsEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: sxth r1, r1
+; CHECK-T2-NEXT: uxtb r0, r0
+; CHECK-T2-NEXT: rsbs r1, r1, #0
+; CHECK-T2-NEXT: subs r0, r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %a to i32
+ %conv1 = sext i16 %b to i32
+ %add = sub nsw i32 0, %conv1
+ %cmp = icmp ne i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @test_NE_IccEbT(i8 %a, i8 %b) {
+; CHECK-ARM-LABEL: test_NE_IccEbT:
+; CHECK-ARM: @ %bb.0: @ %entry
+; CHECK-ARM-NEXT: uxtb r1, r1
+; CHECK-ARM-NEXT: uxtb r0, r0
+; CHECK-ARM-NEXT: rsb r1, r1, #0
+; CHECK-ARM-NEXT: subs r0, r0, r1
+; CHECK-ARM-NEXT: movwne r0, #1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: test_NE_IccEbT:
+; CHECK-T1: @ %bb.0: @ %entry
+; CHECK-T1-NEXT: movs r2, #255
+; CHECK-T1-NEXT: ands r0, r2
+; CHECK-T1-NEXT: ands r1, r2
+; CHECK-T1-NEXT: rsbs r1, r1, #0
+; CHECK-T1-NEXT: subs r0, r0, r1
+; CHECK-T1-NEXT: subs r1, r0, #1
+; CHECK-T1-NEXT: sbcs r0, r1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: test_NE_IccEbT:
+; CHECK-T2: @ %bb.0: @ %entry
+; CHECK-T2-NEXT: uxtb r1, r1
+; CHECK-T2-NEXT: uxtb r0, r0
+; CHECK-T2-NEXT: rsbs r1, r1, #0
+; CHECK-T2-NEXT: subs r0, r0, r1
+; CHECK-T2-NEXT: it ne
+; CHECK-T2-NEXT: movne r0, #1
+; CHECK-T2-NEXT: bx lr
+entry:
+ %conv = zext i8 %a to i32
+ %conv1 = zext i8 %b to i32
+ %add = sub nsw i32 0, %conv1
+ %cmp = icmp ne i32 %conv, %add
+ ret i1 %cmp
+}
+
+define i1 @cmn_large_imm(i32 %a) {
+; CHECK-ARM-LABEL: cmn_large_imm:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r2, #64765
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: movt r2, #64764
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwgt r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: cmn_large_imm:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: ldr r1, .LCPI32_0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: bgt .LBB32_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB32_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI32_0:
+; CHECK-T1-NEXT: .long 4244438269 @ 0xfcfcfcfd
+;
+; CHECK-T2-LABEL: cmn_large_imm:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmn.w r0, #50529027
+; CHECK-T2-NEXT: it gt
+; CHECK-T2-NEXT: movgt r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp sgt i32 %a, -50529027
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_slt(i32 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_slt:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r2, #4097
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: movt r2, #65281
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwlt r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_slt:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: ldr r1, .LCPI33_0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: blt .LBB33_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB33_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI33_0:
+; CHECK-T1-NEXT: .long 4278259713 @ 0xff011001
+;
+; CHECK-T2-LABEL: almost_immediate_neg_slt:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r2, #4097
+; CHECK-T2-NEXT: movt r2, #65281
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it lt
+; CHECK-T2-NEXT: movlt r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp slt i32 %x, -16707583
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_slt_64(i64 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_slt_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r3, #4097
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: movt r3, #65281
+; CHECK-ARM-NEXT: subs r0, r0, r3
+; CHECK-ARM-NEXT: mvn r12, #0
+; CHECK-ARM-NEXT: sbcs r0, r1, r12
+; CHECK-ARM-NEXT: movwlt r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_slt_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: movs r2, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: ldr r3, .LCPI34_0
+; CHECK-T1-NEXT: adds r2, r2, r3
+; CHECK-T1-NEXT: adcs r1, r0
+; CHECK-T1-NEXT: bge .LBB34_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB34_2:
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI34_0:
+; CHECK-T1-NEXT: .long 16707583 @ 0xfeefff
+;
+; CHECK-T2-LABEL: almost_immediate_neg_slt_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r3, #4097
+; CHECK-T2-NEXT: movt r3, #65281
+; CHECK-T2-NEXT: subs r0, r0, r3
+; CHECK-T2-NEXT: mov.w r2, #0
+; CHECK-T2-NEXT: sbcs r0, r1, #-1
+; CHECK-T2-NEXT: it lt
+; CHECK-T2-NEXT: movlt r2, #1
+; CHECK-T2-NEXT: mov r0, r2
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp slt i64 %x, -16707583
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_sge(i32 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_sge:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r2, #4096
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: movt r2, #65281
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwgt r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_sge:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: ldr r1, .LCPI35_0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: bgt .LBB35_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB35_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI35_0:
+; CHECK-T1-NEXT: .long 4278259712 @ 0xff011000
+;
+; CHECK-T2-LABEL: almost_immediate_neg_sge:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r2, #4096
+; CHECK-T2-NEXT: movt r2, #65281
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it gt
+; CHECK-T2-NEXT: movgt r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp sge i32 %x, -16707583
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_sge_64(i64 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_sge_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r3, #4096
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: movt r3, #65281
+; CHECK-ARM-NEXT: subs r0, r3, r0
+; CHECK-ARM-NEXT: mvn r12, #0
+; CHECK-ARM-NEXT: sbcs r0, r12, r1
+; CHECK-ARM-NEXT: movwlt r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_sge_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: .save {r4, lr}
+; CHECK-T1-NEXT: push {r4, lr}
+; CHECK-T1-NEXT: movs r2, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: mvns r3, r0
+; CHECK-T1-NEXT: ldr r4, .LCPI36_0
+; CHECK-T1-NEXT: subs r2, r4, r2
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: bge .LBB36_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB36_2:
+; CHECK-T1-NEXT: pop {r4}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI36_0:
+; CHECK-T1-NEXT: .long 4278259712 @ 0xff011000
+;
+; CHECK-T2-LABEL: almost_immediate_neg_sge_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r3, #4096
+; CHECK-T2-NEXT: movt r3, #65281
+; CHECK-T2-NEXT: mov.w r12, #-1
+; CHECK-T2-NEXT: subs r0, r3, r0
+; CHECK-T2-NEXT: mov.w r2, #0
+; CHECK-T2-NEXT: sbcs.w r0, r12, r1
+; CHECK-T2-NEXT: it lt
+; CHECK-T2-NEXT: movlt r2, #1
+; CHECK-T2-NEXT: mov r0, r2
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp sge i64 %x, -16707583
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_uge(i32 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_uge:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r2, #4096
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: movt r2, #65281
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwhi r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_uge:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: ldr r1, .LCPI37_0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: bhi .LBB37_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB37_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI37_0:
+; CHECK-T1-NEXT: .long 4278259712 @ 0xff011000
+;
+; CHECK-T2-LABEL: almost_immediate_neg_uge:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r2, #4096
+; CHECK-T2-NEXT: movt r2, #65281
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it hi
+; CHECK-T2-NEXT: movhi r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp uge i32 %x, -16707583
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_uge_64(i64 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_uge_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r3, #4096
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: movt r3, #65281
+; CHECK-ARM-NEXT: subs r0, r3, r0
+; CHECK-ARM-NEXT: mvn r12, #0
+; CHECK-ARM-NEXT: sbcs r0, r12, r1
+; CHECK-ARM-NEXT: movwlo r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_uge_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: .save {r4, lr}
+; CHECK-T1-NEXT: push {r4, lr}
+; CHECK-T1-NEXT: movs r2, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: mvns r3, r0
+; CHECK-T1-NEXT: ldr r4, .LCPI38_0
+; CHECK-T1-NEXT: subs r2, r4, r2
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: bhs .LBB38_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB38_2:
+; CHECK-T1-NEXT: pop {r4}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI38_0:
+; CHECK-T1-NEXT: .long 4278259712 @ 0xff011000
+;
+; CHECK-T2-LABEL: almost_immediate_neg_uge_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r3, #4096
+; CHECK-T2-NEXT: movt r3, #65281
+; CHECK-T2-NEXT: mov.w r12, #-1
+; CHECK-T2-NEXT: subs r0, r3, r0
+; CHECK-T2-NEXT: mov.w r2, #0
+; CHECK-T2-NEXT: sbcs.w r0, r12, r1
+; CHECK-T2-NEXT: it lo
+; CHECK-T2-NEXT: movlo r2, #1
+; CHECK-T2-NEXT: mov r0, r2
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp uge i64 %x, -16707583
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_ult(i32 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_ult:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r2, #4097
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: movt r2, #65281
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwlo r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_ult:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: ldr r1, .LCPI39_0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: blo .LBB39_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB39_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI39_0:
+; CHECK-T1-NEXT: .long 4278259713 @ 0xff011001
+;
+; CHECK-T2-LABEL: almost_immediate_neg_ult:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r2, #4097
+; CHECK-T2-NEXT: movt r2, #65281
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it lo
+; CHECK-T2-NEXT: movlo r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp ult i32 %x, -16707583
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_ult_64(i64 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_ult_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r3, #4097
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: movt r3, #65281
+; CHECK-ARM-NEXT: subs r0, r0, r3
+; CHECK-ARM-NEXT: mvn r12, #0
+; CHECK-ARM-NEXT: sbcs r0, r1, r12
+; CHECK-ARM-NEXT: movwlo r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_ult_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: movs r2, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: ldr r3, .LCPI40_0
+; CHECK-T1-NEXT: adds r2, r2, r3
+; CHECK-T1-NEXT: adcs r1, r0
+; CHECK-T1-NEXT: bhs .LBB40_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB40_2:
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI40_0:
+; CHECK-T1-NEXT: .long 16707583 @ 0xfeefff
+;
+; CHECK-T2-LABEL: almost_immediate_neg_ult_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r3, #4097
+; CHECK-T2-NEXT: movt r3, #65281
+; CHECK-T2-NEXT: subs r0, r0, r3
+; CHECK-T2-NEXT: mov.w r2, #0
+; CHECK-T2-NEXT: sbcs r0, r1, #-1
+; CHECK-T2-NEXT: it lo
+; CHECK-T2-NEXT: movlo r2, #1
+; CHECK-T2-NEXT: mov r0, r2
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp ult i64 %x, -16707583
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_sle(i32 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_sle:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r2, #4096
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: movt r2, #65280
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwlt r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_sle:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: ldr r1, .LCPI41_0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: blt .LBB41_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB41_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI41_0:
+; CHECK-T1-NEXT: .long 4278194176 @ 0xff001000
+;
+; CHECK-T2-LABEL: almost_immediate_neg_sle:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r2, #4096
+; CHECK-T2-NEXT: movt r2, #65280
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it lt
+; CHECK-T2-NEXT: movlt r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp sle i32 %x, -16773121
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_sle_64(i64 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_sle_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r3, #4096
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: movt r3, #65280
+; CHECK-ARM-NEXT: subs r0, r0, r3
+; CHECK-ARM-NEXT: mvn r12, #0
+; CHECK-ARM-NEXT: sbcs r0, r1, r12
+; CHECK-ARM-NEXT: movwlt r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_sle_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: movs r2, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: ldr r3, .LCPI42_0
+; CHECK-T1-NEXT: adds r2, r2, r3
+; CHECK-T1-NEXT: adcs r1, r0
+; CHECK-T1-NEXT: bge .LBB42_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB42_2:
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI42_0:
+; CHECK-T1-NEXT: .long 16773120 @ 0xfff000
+;
+; CHECK-T2-LABEL: almost_immediate_neg_sle_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r3, #4096
+; CHECK-T2-NEXT: movt r3, #65280
+; CHECK-T2-NEXT: subs r0, r0, r3
+; CHECK-T2-NEXT: mov.w r2, #0
+; CHECK-T2-NEXT: sbcs r0, r1, #-1
+; CHECK-T2-NEXT: it lt
+; CHECK-T2-NEXT: movlt r2, #1
+; CHECK-T2-NEXT: mov r0, r2
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp sle i64 %x, -16773121
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_sgt(i32 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_sgt:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r2, #4095
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: movt r2, #65280
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwgt r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_sgt:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: ldr r1, .LCPI43_0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: bgt .LBB43_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB43_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI43_0:
+; CHECK-T1-NEXT: .long 4278194175 @ 0xff000fff
+;
+; CHECK-T2-LABEL: almost_immediate_neg_sgt:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r2, #4095
+; CHECK-T2-NEXT: movt r2, #65280
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it gt
+; CHECK-T2-NEXT: movgt r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp sgt i32 %x, -16773121
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_sgt_64(i64 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_sgt_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r3, #4095
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: movt r3, #65280
+; CHECK-ARM-NEXT: subs r0, r3, r0
+; CHECK-ARM-NEXT: mvn r12, #0
+; CHECK-ARM-NEXT: sbcs r0, r12, r1
+; CHECK-ARM-NEXT: movwlt r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_sgt_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: .save {r4, lr}
+; CHECK-T1-NEXT: push {r4, lr}
+; CHECK-T1-NEXT: movs r2, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: mvns r3, r0
+; CHECK-T1-NEXT: ldr r4, .LCPI44_0
+; CHECK-T1-NEXT: subs r2, r4, r2
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: bge .LBB44_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB44_2:
+; CHECK-T1-NEXT: pop {r4}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI44_0:
+; CHECK-T1-NEXT: .long 4278194175 @ 0xff000fff
+;
+; CHECK-T2-LABEL: almost_immediate_neg_sgt_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r3, #4095
+; CHECK-T2-NEXT: movt r3, #65280
+; CHECK-T2-NEXT: mov.w r12, #-1
+; CHECK-T2-NEXT: subs r0, r3, r0
+; CHECK-T2-NEXT: mov.w r2, #0
+; CHECK-T2-NEXT: sbcs.w r0, r12, r1
+; CHECK-T2-NEXT: it lt
+; CHECK-T2-NEXT: movlt r2, #1
+; CHECK-T2-NEXT: mov r0, r2
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp sgt i64 %x, -16773121
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_ule(i32 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_ule:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r2, #4096
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: movt r2, #65280
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwlo r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_ule:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: ldr r1, .LCPI45_0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: blo .LBB45_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB45_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI45_0:
+; CHECK-T1-NEXT: .long 4278194176 @ 0xff001000
+;
+; CHECK-T2-LABEL: almost_immediate_neg_ule:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r2, #4096
+; CHECK-T2-NEXT: movt r2, #65280
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it lo
+; CHECK-T2-NEXT: movlo r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp ule i32 %x, -16773121
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_ule_64(i64 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_ule_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r3, #4096
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: movt r3, #65280
+; CHECK-ARM-NEXT: subs r0, r0, r3
+; CHECK-ARM-NEXT: mvn r12, #0
+; CHECK-ARM-NEXT: sbcs r0, r1, r12
+; CHECK-ARM-NEXT: movwlo r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_ule_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: movs r2, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: ldr r3, .LCPI46_0
+; CHECK-T1-NEXT: adds r2, r2, r3
+; CHECK-T1-NEXT: adcs r1, r0
+; CHECK-T1-NEXT: bhs .LBB46_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB46_2:
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI46_0:
+; CHECK-T1-NEXT: .long 16773120 @ 0xfff000
+;
+; CHECK-T2-LABEL: almost_immediate_neg_ule_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r3, #4096
+; CHECK-T2-NEXT: movt r3, #65280
+; CHECK-T2-NEXT: subs r0, r0, r3
+; CHECK-T2-NEXT: mov.w r2, #0
+; CHECK-T2-NEXT: sbcs r0, r1, #-1
+; CHECK-T2-NEXT: it lo
+; CHECK-T2-NEXT: movlo r2, #1
+; CHECK-T2-NEXT: mov r0, r2
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp ule i64 %x, -16773121
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_ugt(i32 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_ugt:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r2, #4095
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: movt r2, #65280
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwhi r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_ugt:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: ldr r1, .LCPI47_0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: bhi .LBB47_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB47_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI47_0:
+; CHECK-T1-NEXT: .long 4278194175 @ 0xff000fff
+;
+; CHECK-T2-LABEL: almost_immediate_neg_ugt:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r2, #4095
+; CHECK-T2-NEXT: movt r2, #65280
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it hi
+; CHECK-T2-NEXT: movhi r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp ugt i32 %x, -16773121
+ ret i1 %cmp
+}
+
+define i1 @almost_immediate_neg_ugt_64(i64 %x) {
+; CHECK-ARM-LABEL: almost_immediate_neg_ugt_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: movw r3, #4095
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: movt r3, #65280
+; CHECK-ARM-NEXT: subs r0, r3, r0
+; CHECK-ARM-NEXT: mvn r12, #0
+; CHECK-ARM-NEXT: sbcs r0, r12, r1
+; CHECK-ARM-NEXT: movwlo r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: almost_immediate_neg_ugt_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: .save {r4, lr}
+; CHECK-T1-NEXT: push {r4, lr}
+; CHECK-T1-NEXT: movs r2, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: mvns r3, r0
+; CHECK-T1-NEXT: ldr r4, .LCPI48_0
+; CHECK-T1-NEXT: subs r2, r4, r2
+; CHECK-T1-NEXT: sbcs r3, r1
+; CHECK-T1-NEXT: bhs .LBB48_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB48_2:
+; CHECK-T1-NEXT: pop {r4}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+; CHECK-T1-NEXT: .p2align 2
+; CHECK-T1-NEXT: @ %bb.3:
+; CHECK-T1-NEXT: .LCPI48_0:
+; CHECK-T1-NEXT: .long 4278194175 @ 0xff000fff
+;
+; CHECK-T2-LABEL: almost_immediate_neg_ugt_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: movw r3, #4095
+; CHECK-T2-NEXT: movt r3, #65280
+; CHECK-T2-NEXT: mov.w r12, #-1
+; CHECK-T2-NEXT: subs r0, r3, r0
+; CHECK-T2-NEXT: mov.w r2, #0
+; CHECK-T2-NEXT: sbcs.w r0, r12, r1
+; CHECK-T2-NEXT: it lo
+; CHECK-T2-NEXT: movlo r2, #1
+; CHECK-T2-NEXT: mov r0, r2
+; CHECK-T2-NEXT: bx lr
+ %cmp = icmp ugt i64 %x, -16773121
+ ret i1 %cmp
+}
+
+define i1 @cmn_nsw(i32 %a, i32 %b) {
+; CHECK-ARM-LABEL: cmn_nsw:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: rsb r2, r1, #0
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwgt r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: cmn_nsw:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: rsbs r1, r1, #0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: bgt .LBB49_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB49_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: cmn_nsw:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: rsbs r2, r1, #0
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it gt
+; CHECK-T2-NEXT: movgt r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %sub = sub nsw i32 0, %b
+ %cmp = icmp sgt i32 %a, %sub
+ ret i1 %cmp
+}
+
+define i1 @cmn_nsw_64(i64 %a, i64 %b) {
+; CHECK-ARM-LABEL: cmn_nsw_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: rsbs r12, r2, #0
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: rsc r3, r3, #0
+; CHECK-ARM-NEXT: subs r0, r12, r0
+; CHECK-ARM-NEXT: sbcs r0, r3, r1
+; CHECK-ARM-NEXT: movwlt r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: cmn_nsw_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: .save {r4, r5, r7, lr}
+; CHECK-T1-NEXT: push {r4, r5, r7, lr}
+; CHECK-T1-NEXT: movs r4, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: mov r12, r0
+; CHECK-T1-NEXT: mov r5, r12
+; CHECK-T1-NEXT: sbcs r5, r3
+; CHECK-T1-NEXT: subs r2, r2, r4
+; CHECK-T1-NEXT: sbcs r5, r1
+; CHECK-T1-NEXT: bge .LBB50_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB50_2:
+; CHECK-T1-NEXT: pop {r4, r5, r7}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+;
+; CHECK-T2-LABEL: cmn_nsw_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: mov.w r12, #0
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: sbc.w r3, r12, r3
+; CHECK-T2-NEXT: subs r0, r2, r0
+; CHECK-T2-NEXT: sbcs.w r0, r3, r1
+; CHECK-T2-NEXT: it lt
+; CHECK-T2-NEXT: movlt.w r12, #1
+; CHECK-T2-NEXT: mov r0, r12
+; CHECK-T2-NEXT: bx lr
+ %sub = sub nsw i64 0, %b
+ %cmp = icmp sgt i64 %a, %sub
+ ret i1 %cmp
+}
+
+define i1 @cmn_nsw_neg(i32 %a, i32 %b) {
+; CHECK-ARM-LABEL: cmn_nsw_neg:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: rsb r2, r1, #0
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: cmp r0, r2
+; CHECK-ARM-NEXT: movwgt r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: cmn_nsw_neg:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: rsbs r1, r1, #0
+; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: bgt .LBB51_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB51_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: cmn_nsw_neg:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: rsbs r2, r1, #0
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: it gt
+; CHECK-T2-NEXT: movgt r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %sub = sub i32 0, %b
+ %cmp = icmp sgt i32 %a, %sub
+ ret i1 %cmp
+}
+
+define i1 @cmn_swap(i32 %a, i32 %b) {
+; CHECK-ARM-LABEL: cmn_swap:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: rsb r2, r1, #0
+; CHECK-ARM-NEXT: mov r1, #0
+; CHECK-ARM-NEXT: cmp r2, r0
+; CHECK-ARM-NEXT: movwgt r1, #1
+; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: cmn_swap:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: rsbs r1, r1, #0
+; CHECK-T1-NEXT: cmp r1, r0
+; CHECK-T1-NEXT: bgt .LBB52_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: bx lr
+; CHECK-T1-NEXT: .LBB52_2:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: bx lr
+;
+; CHECK-T2-LABEL: cmn_swap:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: rsbs r2, r1, #0
+; CHECK-T2-NEXT: movs r1, #0
+; CHECK-T2-NEXT: cmp r2, r0
+; CHECK-T2-NEXT: it gt
+; CHECK-T2-NEXT: movgt r1, #1
+; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: bx lr
+ %sub = sub nsw i32 0, %b
+ %cmp = icmp sgt i32 %sub, %a
+ ret i1 %cmp
+}
+
+
+define i1 @cmn_nsw_neg_64(i64 %a, i64 %b) {
+; CHECK-ARM-LABEL: cmn_nsw_neg_64:
+; CHECK-ARM: @ %bb.0:
+; CHECK-ARM-NEXT: rsbs r12, r2, #0
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: rsc r3, r3, #0
+; CHECK-ARM-NEXT: subs r0, r12, r0
+; CHECK-ARM-NEXT: sbcs r0, r3, r1
+; CHECK-ARM-NEXT: movwlt r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
+; CHECK-ARM-NEXT: bx lr
+;
+; CHECK-T1-LABEL: cmn_nsw_neg_64:
+; CHECK-T1: @ %bb.0:
+; CHECK-T1-NEXT: .save {r4, r5, r7, lr}
+; CHECK-T1-NEXT: push {r4, r5, r7, lr}
+; CHECK-T1-NEXT: movs r4, r0
+; CHECK-T1-NEXT: movs r0, #0
+; CHECK-T1-NEXT: rsbs r2, r2, #0
+; CHECK-T1-NEXT: mov r12, r0
+; CHECK-T1-NEXT: mov r5, r12
+; CHECK-T1-NEXT: sbcs r5, r3
+; CHECK-T1-NEXT: subs r2, r2, r4
+; CHECK-T1-NEXT: sbcs r5, r1
+; CHECK-T1-NEXT: bge .LBB53_2
+; CHECK-T1-NEXT: @ %bb.1:
+; CHECK-T1-NEXT: movs r0, #1
+; CHECK-T1-NEXT: .LBB53_2:
+; CHECK-T1-NEXT: pop {r4, r5, r7}
+; CHECK-T1-NEXT: pop {r1}
+; CHECK-T1-NEXT: bx r1
+;
+; CHECK-T2-LABEL: cmn_nsw_neg_64:
+; CHECK-T2: @ %bb.0:
+; CHECK-T2-NEXT: mov.w r12, #0
+; CHECK-T2-NEXT: rsbs r2, r2, #0
+; CHECK-T2-NEXT: sbc.w r3, r12, r3
+; CHECK-T2-NEXT: subs r0, r2, r0
+; CHECK-T2-NEXT: sbcs.w r0, r3, r1
+; CHECK-T2-NEXT: it lt
+; CHECK-T2-NEXT: movlt.w r12, #1
+; CHECK-T2-NEXT: mov r0, r12
+; CHECK-T2-NEXT: bx lr
+ %sub = sub i64 0, %b
+ %cmp = icmp sgt i64 %a, %sub
+ ret i1 %cmp
+}
>From 5cf7cd063d611b87673cfa5545c2b35a569ac03f Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 13 Oct 2025 12:35:07 -0400
Subject: [PATCH 2/2] [ARM] Enable creation of ARMISD::CMN nodes
Map ARMISD::CMN to tCMN instead of armcmpz.
Rename the cmn instructions to match this new reality.
Also use the new isCMN to simplify LowerCMP.
---
llvm/lib/Target/ARM/ARMFeatures.h | 2 +-
llvm/lib/Target/ARM/ARMISelLowering.cpp | 72 +++++++++++++--------
llvm/lib/Target/ARM/ARMInstrInfo.td | 32 +++++----
llvm/lib/Target/ARM/ARMInstrThumb.td | 21 +++---
llvm/lib/Target/ARM/ARMInstrThumb2.td | 24 ++++---
llvm/lib/Target/ARM/ARMLatencyMutations.cpp | 2 +-
llvm/lib/Target/ARM/ARMScheduleM55.td | 4 +-
llvm/lib/Target/ARM/ARMScheduleM7.td | 2 +-
llvm/lib/Target/ARM/ARMScheduleM85.td | 4 +-
llvm/lib/Target/ARM/ARMScheduleR52.td | 6 +-
llvm/lib/Target/ARM/Thumb2SizeReduction.cpp | 4 +-
llvm/test/CodeGen/ARM/cmp-to-cmn.ll | 46 ++++++-------
llvm/test/MC/ARM/arm-shift-encoding.s | 2 +-
llvm/test/MC/ARM/thumb-shift-encoding.s | 2 +-
14 files changed, 117 insertions(+), 106 deletions(-)
diff --git a/llvm/lib/Target/ARM/ARMFeatures.h b/llvm/lib/Target/ARM/ARMFeatures.h
index 99e0ef05b5e21..eeb67abe27512 100644
--- a/llvm/lib/Target/ARM/ARMFeatures.h
+++ b/llvm/lib/Target/ARM/ARMFeatures.h
@@ -51,7 +51,7 @@ inline bool isV8EligibleForIT(const InstrType *Instr) {
// Outside of an IT block, these set CPSR.
return IsCPSRDead(Instr);
case ARM::tADDrSPi:
- case ARM::tCMNz:
+ case ARM::tCMN:
case ARM::tCMPi8:
case ARM::tCMPr:
case ARM::tLDRBi:
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 8122db27a9f67..db3267045bbc5 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -4683,6 +4683,29 @@ static bool isFloatingPointZero(SDValue Op) {
return false;
}
+static bool isSafeSignedCMN(SDValue Op, SelectionDAG &DAG) {
+ // 0 - INT_MIN sign wraps, so no signed wrap means cmn is safe.
+ if (Op->getFlags().hasNoSignedWrap())
+ return true;
+
+ // We can still figure out if the second operand is safe to use
+ // in a CMN instruction by checking if it is known to be not the minimum
+ // signed value. If it is not, then we can safely use CMN.
+ // Note: We can eventually remove this check and simply rely on
+ // Op->getFlags().hasNoSignedWrap() once SelectionDAG/ISelLowering
+ // consistently sets them appropriately when making said nodes.
+
+ KnownBits KnownSrc = DAG.computeKnownBits(Op.getOperand(1));
+ return !KnownSrc.getSignedMinValue().isMinSignedValue();
+}
+
+static bool isCMN(SDValue Op, ISD::CondCode CC, SelectionDAG &DAG) {
+ return Op.getOpcode() == ISD::SUB && isNullConstant(Op.getOperand(0)) &&
+ (isIntEqualitySetCC(CC) ||
+ (isUnsignedIntSetCC(CC) && DAG.isKnownNeverZero(Op.getOperand(1))) ||
+ (isSignedIntSetCC(CC) && isSafeSignedCMN(Op, DAG)));
+}
+
/// Returns appropriate ARM CMP (cmp) and corresponding condition code for
/// the given operands.
SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
@@ -4816,6 +4839,21 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
CompareType = ARMISD::CMPZ;
break;
}
+
+ // TODO: Remove CMPZ check once we generalize and remove the CMPZ enum from
+ // the codebase.
+
+ // TODO: When we have a solution to the vselect predicate not allowing pl/mi
+ // all the time, allow those cases to be cmn too no matter what.
+ if (CompareType != ARMISD::CMPZ && isCMN(RHS, CC, DAG)) {
+ CompareType = ARMISD::CMN;
+ RHS = RHS.getOperand(1);
+ } else if (CompareType != ARMISD::CMPZ && isCMN(LHS, CC, DAG)) {
+ CompareType = ARMISD::CMN;
+ LHS = LHS.getOperand(1);
+ CondCode = IntCCToARMCC(ISD::getSetCCSwappedOperands(CC));
+ }
+
ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
return DAG.getNode(CompareType, dl, FlagsVT, LHS, RHS);
}
@@ -10532,34 +10570,12 @@ SDValue ARMTargetLowering::LowerCMP(SDValue Op, SelectionDAG &DAG) const {
// Optimization: if RHS is a subtraction against 0, use ADDC instead of SUBC
unsigned Opcode = ARMISD::SUBC;
- // Check if RHS is a subtraction against 0: (0 - X)
- if (RHS.getOpcode() == ISD::SUB) {
- SDValue SubLHS = RHS.getOperand(0);
- SDValue SubRHS = RHS.getOperand(1);
-
- // Check if it's 0 - X
- if (isNullConstant(SubLHS)) {
- bool CanUseAdd = false;
- if (IsSigned) {
- // For SCMP: only if X is known to never be INT_MIN (to avoid overflow)
- if (RHS->getFlags().hasNoSignedWrap() || !DAG.computeKnownBits(SubRHS)
- .getSignedMinValue()
- .isMinSignedValue()) {
- CanUseAdd = true;
- }
- } else {
- // For UCMP: only if X is known to never be zero
- if (DAG.isKnownNeverZero(SubRHS)) {
- CanUseAdd = true;
- }
- }
-
- if (CanUseAdd) {
- Opcode = ARMISD::ADDC;
- RHS = SubRHS; // Replace RHS with X, so we do LHS + X instead of
- // LHS - (0 - X)
- }
- }
+ // Doesn't matter as it's a 3-way but let's just send in a signed comparison
+ // if signed or an unsigned comparison if unsigned.
+ ISD::CondCode CC = IsSigned ? ISD::SETGT : ISD::SETUGT;
+ if (isCMN(RHS, CC, DAG)) {
+ Opcode = ARMISD::ADDC;
+ RHS = RHS.getOperand(1);
}
// Generate the operation with flags
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 53be1677b96e3..685f8cd4a5b29 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -206,9 +206,9 @@ def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64,
def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp>;
-def ARMcmn : SDNode<"ARMISD::CMN", SDT_ARMCmp>;
+def ARMcmn : SDNode<"ARMISD::CMN", SDT_ARMCmp, [SDNPCommutative]>;
-def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, [SDNPCommutative]>;
+def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,[SDNPCommutative]>;
def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
@@ -4944,10 +4944,10 @@ def CMNri : AI1<0b1011, (outs), (ins GPR:$Rn, mod_imm:$imm), DPFrm, IIC_iCMPi,
}
// CMN register-register/shift
-def CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr,
+def CMNrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr,
"cmn", "\t$Rn, $Rm",
- [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
- GPR:$Rn, GPR:$Rm))]>, Sched<[WriteCMP, ReadALU, ReadALU]> {
+ [(set CPSR, (ARMcmn GPR:$Rn, GPR:$Rm))]>,
+ Sched<[WriteCMP, ReadALU, ReadALU]> {
bits<4> Rn;
bits<4> Rm;
let isCommutable = 1;
@@ -4961,12 +4961,11 @@ def CMNzrr : AI1<0b1011, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, IIC_iCMPr,
let Unpredictable{15-12} = 0b1111;
}
-def CMNzrsi : AI1<0b1011, (outs),
+def CMNrsi : AI1<0b1011, (outs),
(ins GPR:$Rn, so_reg_imm:$shift), DPSoRegImmFrm, IIC_iCMPsr,
"cmn", "\t$Rn, $shift",
- [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
- GPR:$Rn, so_reg_imm:$shift))]>,
- Sched<[WriteCMPsi, ReadALU]> {
+ [(set CPSR, (ARMcmn GPR:$Rn, so_reg_imm:$shift))]>,
+ Sched<[WriteCMPsi, ReadALU]> {
bits<4> Rn;
bits<12> shift;
let Inst{25} = 0;
@@ -4980,12 +4979,11 @@ def CMNzrsi : AI1<0b1011, (outs),
let Unpredictable{15-12} = 0b1111;
}
-def CMNzrsr : AI1<0b1011, (outs),
+def CMNrsr : AI1<0b1011, (outs),
(ins GPRnopc:$Rn, so_reg_reg:$shift), DPSoRegRegFrm, IIC_iCMPsr,
"cmn", "\t$Rn, $shift",
- [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
- GPRnopc:$Rn, so_reg_reg:$shift))]>,
- Sched<[WriteCMPsr, ReadALU]> {
+ [(set CPSR, (ARMcmn GPRnopc:$Rn, so_reg_reg:$shift))]>,
+ Sched<[WriteCMPsr, ReadALU]> {
bits<4> Rn;
bits<12> shift;
let Inst{25} = 0;
@@ -5003,11 +5001,17 @@ def CMNzrsr : AI1<0b1011, (outs),
}
+// ARMcmpZ patterns for CMN (compare-to-zero with negated operands)
def : ARMPat<(ARMcmp GPR:$src, mod_imm_neg:$imm),
(CMNri GPR:$src, mod_imm_neg:$imm)>;
-
def : ARMPat<(ARMcmpZ GPR:$src, mod_imm_neg:$imm),
(CMNri GPR:$src, mod_imm_neg:$imm)>;
+def : ARMPat<(ARMcmpZ GPR:$src, (ineg GPR:$rhs)),
+ (CMNrr GPR:$src, GPR:$rhs)>;
+def : ARMPat<(ARMcmpZ GPR:$src, (ineg so_reg_imm:$rhs)),
+ (CMNrsi GPR:$src, so_reg_imm:$rhs)>;
+def : ARMPat<(ARMcmpZ GPRnopc:$src, (ineg so_reg_reg:$rhs)),
+ (CMNrsr GPRnopc:$src, so_reg_reg:$rhs)>;
// Note that TST/TEQ don't set all the same flags that CMP does!
defm TST : AI1_cmp_irs<0b1000, "tst",
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td
index 0c5ea3e0fa8d5..032d0467509e2 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -1089,7 +1089,8 @@ def tASRrr : // A8.6.15
T1sItDPEncode<0b0100, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm),
IIC_iMOVsr,
"asr", "\t$Rdn, $Rm",
- [(set tGPR:$Rdn, (sra tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
+ [(set tGPR:$Rdn, (sra tGPR:$Rn, tGPR:$Rm))]>,
+ Sched<[WriteALU]>;
// BIC register
def tBIC : // A8.6.20
@@ -1101,21 +1102,12 @@ def tBIC : // A8.6.20
// CMN register
let isCompare = 1, Defs = [CPSR] in {
-//FIXME: Disable CMN, as CCodes are backwards from compare expectations
-// Compare-to-zero still works out, just not the relationals
-//def tCMN : // A8.6.33
-// T1pIDPEncode<0b1011, (outs), (ins tGPR:$lhs, tGPR:$rhs),
-// IIC_iCMPr,
-// "cmn", "\t$lhs, $rhs",
-// [(set CPSR, (ARMcmp tGPR:$lhs, (ineg tGPR:$rhs)))]>;
-
-def tCMNz : // A8.6.33
+def tCMN : // A8.6.33
T1pIDPEncode<0b1011, (outs), (ins tGPR:$Rn, tGPR:$Rm),
IIC_iCMPr,
"cmn", "\t$Rn, $Rm",
- [(set CPSR, (ARMcmpZ tGPR:$Rn, (ineg tGPR:$Rm)))]>,
- Sched<[WriteCMP]>;
-
+ [(set CPSR, (ARMcmn tGPR:$Rn, tGPR:$Rm))]>,
+ Sched<[WriteCMP]>;
} // isCompare = 1, Defs = [CPSR]
// CMP immediate
@@ -1569,6 +1561,9 @@ def tInt_WIN_eh_sjlj_longjmp
// Comparisons
def : T1Pat<(ARMcmpZ tGPR:$Rn, imm0_255:$imm8),
(tCMPi8 tGPR:$Rn, imm0_255:$imm8)>;
+// Fold compare-to-zero of a negated register into CMN register form.
+def : T1Pat<(ARMcmpZ tGPR:$Rn, (ineg tGPR:$Rm)),
+ (tCMN tGPR:$Rn, tGPR:$Rm)>;
def : T1Pat<(ARMcmpZ tGPR:$Rn, tGPR:$Rm),
(tCMPr tGPR:$Rn, tGPR:$Rm)>;
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index c229c8e4491df..d0e44b55eecc1 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -3495,12 +3495,11 @@ let isCompare = 1, Defs = [CPSR] in {
let Inst{11-8} = 0b1111; // Rd
}
// register
- def t2CMNzrr : T2TwoRegCmp<
+ def t2CMNrr : T2TwoRegCmp<
(outs), (ins GPRnopc:$Rn, rGPR:$Rm), IIC_iCMPr,
"cmn", ".w\t$Rn, $Rm",
- [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
- GPRnopc:$Rn, rGPR:$Rm))]>,
- Sched<[WriteCMP, ReadALU, ReadALU]> {
+ [(set CPSR, (ARMcmn GPRnopc:$Rn, rGPR:$Rm))]>,
+ Sched<[WriteCMP, ReadALU, ReadALU]> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
let Inst{24-21} = 0b1000;
@@ -3511,12 +3510,11 @@ let isCompare = 1, Defs = [CPSR] in {
let Inst{5-4} = 0b00; // type
}
// shifted register
- def t2CMNzrs : T2OneRegCmpShiftedReg<
+ def t2CMNrs : T2OneRegCmpShiftedReg<
(outs), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), IIC_iCMPsi,
"cmn", ".w\t$Rn, $ShiftedRm",
- [(set CPSR, (BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>
- GPRnopc:$Rn, t2_so_reg:$ShiftedRm))]>,
- Sched<[WriteCMPsi, ReadALU, ReadALU]> {
+ [(set CPSR, (ARMcmn GPRnopc:$Rn, t2_so_reg:$ShiftedRm))]>,
+ Sched<[WriteCMPsi, ReadALU, ReadALU]> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
let Inst{24-21} = 0b1000;
@@ -3531,7 +3529,7 @@ let isCompare = 1, Defs = [CPSR] in {
def : t2InstAlias<"cmn${p} $Rn, $imm",
(t2CMNri GPRnopc:$Rn, t2_so_imm:$imm, pred:$p)>;
def : t2InstAlias<"cmn${p} $Rn, $shift",
- (t2CMNzrs GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>;
+ (t2CMNrs GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>;
def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
(t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
@@ -3539,6 +3537,12 @@ def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
def : T2Pat<(ARMcmpZ GPRnopc:$src, t2_so_imm_neg:$imm),
(t2CMNri GPRnopc:$src, t2_so_imm_neg:$imm)>;
+// Fold compare-to-zero of a negated register into CMN register forms.
+def : T2Pat<(ARMcmpZ GPRnopc:$Rn, (ineg rGPR:$Rm)),
+ (t2CMNrr GPRnopc:$Rn, rGPR:$Rm)>;
+def : T2Pat<(ARMcmpZ GPRnopc:$Rn, (ineg t2_so_reg:$ShiftedRm)),
+ (t2CMNrs GPRnopc:$Rn, t2_so_reg:$ShiftedRm)>;
+
defm t2TST : T2I_cmp_irs<0b0000, "tst", rGPR,
IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>;
@@ -5096,7 +5100,7 @@ def : t2InstAlias<"subw${p} $Rdn, $imm",
// Alias for compares without the ".w" optional width specifier.
def : t2InstAlias<"cmn${p} $Rn, $Rm",
- (t2CMNzrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>;
+ (t2CMNrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>;
def : t2InstAlias<"teq${p} $Rn, $Rm",
(t2TEQrr rGPR:$Rn, rGPR:$Rm, pred:$p)>;
def : t2InstAlias<"tst${p} $Rn, $Rm",
diff --git a/llvm/lib/Target/ARM/ARMLatencyMutations.cpp b/llvm/lib/Target/ARM/ARMLatencyMutations.cpp
index 85bad4f1925a4..bd497f4172406 100644
--- a/llvm/lib/Target/ARM/ARMLatencyMutations.cpp
+++ b/llvm/lib/Target/ARM/ARMLatencyMutations.cpp
@@ -114,7 +114,7 @@ InstructionInformation::InstructionInformation(const ARMBaseInstrInfo *TII) {
std::initializer_list<unsigned> isInlineShiftALUList = {
t2ADCrs, t2ADDSrs, t2ADDrs, t2BICrs, t2EORrs,
t2ORNrs, t2RSBSrs, t2RSBrs, t2SBCrs, t2SUBrs,
- t2SUBSrs, t2CMPrs, t2CMNzrs, t2TEQrs, t2TSTrs,
+ t2SUBSrs, t2CMPrs, t2CMNrs, t2TEQrs, t2TSTrs,
};
for (auto op : isInlineShiftALUList) {
Info[op].IsInlineShiftALU = true;
diff --git a/llvm/lib/Target/ARM/ARMScheduleM55.td b/llvm/lib/Target/ARM/ARMScheduleM55.td
index ff05936e8ba45..de55eafb039d6 100644
--- a/llvm/lib/Target/ARM/ARMScheduleM55.td
+++ b/llvm/lib/Target/ARM/ARMScheduleM55.td
@@ -152,7 +152,7 @@ def : InstRW<[M55WriteDX_SI], (instregex "t2CS(EL|INC|INV|NEG)")>;
// Thumb 2 instructions that could be reduced to a thumb 1 instruction and can
// be dual issued with one of the above. This list is optimistic.
def : InstRW<[M55WriteDX_DI], (instregex "t2ADDC?rr$", "t2ADDrr$",
- "t2ADDSrr$", "t2ANDrr$", "t2ASRr[ir]$", "t2BICrr$", "t2CMNzrr$",
+ "t2ADDSrr$", "t2ANDrr$", "t2ASRr[ir]$", "t2BICrr$", "t2CMNrr$",
"t2CMPr[ir]$", "t2EORrr$", "t2LSLr[ir]$", "t2LSRr[ir]$", "t2MVNr$",
"t2ORRrr$", "t2REV(16|SH)?$", "t2RORrr$", "t2RSBr[ir]$", "t2RSBSri$",
"t2SBCrr$", "t2SUBS?rr$", "t2TEQrr$", "t2TSTrr$", "t2STRi12$",
@@ -161,7 +161,7 @@ def : InstRW<[M55WriteDX_DI], (instregex "t2ADDC?rr$", "t2ADDrr$",
def : InstRW<[M55WriteDX_DI], (instregex "t2SETPAN$", "tADC$", "tADDhirr$",
"tADDrSP$", "tADDrSPi$", "tADDrr$", "tADDspi$", "tADDspr$", "tADR$",
"tAND$", "tASRri$", "tASRrr$", "tBIC$", "tBKPT$", "tCBNZ$", "tCBZ$",
- "tCMNz$", "tCMPhir$", "tCMPi8$", "tCMPr$", "tCPS$", "tEOR$", "tHINT$",
+ "tCMN","tCMPhir$", "tCMPi8$", "tCMPr$", "tCPS$", "tEOR$", "tHINT$",
"tHLT$", "tLSLri$", "tLSLrr$", "tLSRri$", "tLSRrr$", "tMOVSr$",
"tMUL$", "tMVN$", "tORR$", "tPICADD$", "tPOP$", "tPUSH$", "tREV$",
"tREV16$", "tREVSH$", "tROR$", "tRSB$", "tSBC$", "tSETEND$",
diff --git a/llvm/lib/Target/ARM/ARMScheduleM7.td b/llvm/lib/Target/ARM/ARMScheduleM7.td
index 99d2e4a832220..482e417220d3e 100644
--- a/llvm/lib/Target/ARM/ARMScheduleM7.td
+++ b/llvm/lib/Target/ARM/ARMScheduleM7.td
@@ -324,7 +324,7 @@ def M7Ex1ReadNoFastBypass : SchedReadAdvance<-1, [WriteLd, M7LoadLatency1]>;
def : InstRW<[WriteALUsi, M7Ex1ReadNoFastBypass, M7Read_ISS],
(instregex "t2(ADC|ADDS|ADD|BIC|EOR|ORN|ORR|RSBS|RSB|SBC|SUBS)rs$",
- "t2(SUB|CMP|CMNz|TEQ|TST)rs$",
+ "t2(SUB|CMP|CMN|TEQ|TST)rs$",
"t2(A|L)SRs1$")>;
def : InstRW<[WriteALUsi, M7Read_ISS],
(instregex "t2MVNs")>;
diff --git a/llvm/lib/Target/ARM/ARMScheduleM85.td b/llvm/lib/Target/ARM/ARMScheduleM85.td
index e9938d857e6af..beeda468397ec 100644
--- a/llvm/lib/Target/ARM/ARMScheduleM85.td
+++ b/llvm/lib/Target/ARM/ARMScheduleM85.td
@@ -410,7 +410,7 @@ def M85ReadALUsi : SchedReadVariant<[
def : InstRW<[M85WriteALUsi, M85Read_EX1, M85ReadALUsi],
(instregex "t2(ADC|ADDS|BIC|EOR|ORN|ORR|RSBS|RSB|SBC|"
- "SUBS|CMP|CMNz|TEQ|TST)rs$")>;
+ "SUBS|CMP|CMN|TEQ|TST)rs$")>;
def : InstRW<[M85WriteALUsi, M85ReadALUsi],
(instregex "t2MVNs")>;
@@ -419,7 +419,7 @@ def : InstRW<[M85WriteALUsi, M85ReadALUsi],
// shift resource.
def : InstRW<[M85WriteALUsi, M85Read_EX1, M85ReadALUsi],
(instregex "t2(ADC|ADDS|BIC|EOR|ORN|ORR|RSBS|RSB|SBC|"
- "SUBS|CMP|CMNz|TEQ|TST)rr$")>;
+ "SUBS|CMP|CMN|TEQ|TST)rr$")>;
def : InstRW<[M85WriteALUsi, M85ReadALUsi],
(instregex "t2MVNr")>;
diff --git a/llvm/lib/Target/ARM/ARMScheduleR52.td b/llvm/lib/Target/ARM/ARMScheduleR52.td
index c350180baa250..8781ece621ba2 100644
--- a/llvm/lib/Target/ARM/ARMScheduleR52.td
+++ b/llvm/lib/Target/ARM/ARMScheduleR52.td
@@ -330,9 +330,9 @@ def : InstRW<[R52WriteALU_EX1, R52Read_ISS, R52Read_ISS],
(instregex "ASRr", "RORS?r", "LSR", "LSL")>;
def : InstRW<[R52WriteCC, R52Read_EX1], (instregex "CMPri", "CMNri")>;
-def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_EX1], (instregex "CMPrr", "CMNzrr")>;
-def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_ISS], (instregex "CMPrsi", "CMNzrsi")>;
-def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_ISS, R52Read_ISS], (instregex "CMPrsr", "CMNzrsr")>;
+def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_EX1], (instregex "CMPrr", "CMNrr")>;
+def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_ISS], (instregex "CMPrsi", "CMNrsi")>;
+def : InstRW<[R52WriteCC, R52Read_EX1, R52Read_ISS, R52Read_ISS], (instregex "CMPrsr", "CMNrsr")>;
def : InstRW<[R52WriteALU_EX2, R52Read_ISS],
(instregex "t2LDC", "RBIT", "REV", "REV16", "REVSH", "RRX")>;
diff --git a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp
index 18e41297b1734..de1a46ef3682f 100644
--- a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp
+++ b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp
@@ -88,9 +88,7 @@ namespace {
{ ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 1,0,1 },
{ ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 1,0,1 },
{ ARM::t2BICrr, 0, ARM::tBIC, 0, 0, 0, 1, 0,0, 1,0,0 },
- //FIXME: Disable CMN, as CCodes are backwards from compare expectations
- //{ ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0,0,0 },
- { ARM::t2CMNzrr, ARM::tCMNz, 0, 0, 0, 1, 0, 2,0, 0,0,0 },
+ { ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0,0,0 },
{ ARM::t2CMPri, ARM::tCMPi8, 0, 8, 0, 1, 0, 2,0, 0,0,0 },
{ ARM::t2CMPrr, ARM::tCMPhir, 0, 0, 0, 0, 0, 2,0, 0,1,0 },
{ ARM::t2EORrr, 0, ARM::tEOR, 0, 0, 0, 1, 0,0, 1,0,0 },
diff --git a/llvm/test/CodeGen/ARM/cmp-to-cmn.ll b/llvm/test/CodeGen/ARM/cmp-to-cmn.ll
index 12659a55bfc4b..fbf707ccb7838 100644
--- a/llvm/test/CodeGen/ARM/cmp-to-cmn.ll
+++ b/llvm/test/CodeGen/ARM/cmp-to-cmn.ll
@@ -1997,17 +1997,15 @@ define i1 @almost_immediate_neg_ugt_64(i64 %x) {
define i1 @cmn_nsw(i32 %a, i32 %b) {
; CHECK-ARM-LABEL: cmn_nsw:
; CHECK-ARM: @ %bb.0:
-; CHECK-ARM-NEXT: rsb r2, r1, #0
-; CHECK-ARM-NEXT: mov r1, #0
-; CHECK-ARM-NEXT: cmp r0, r2
-; CHECK-ARM-NEXT: movwgt r1, #1
-; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: cmn r0, r1
+; CHECK-ARM-NEXT: movwgt r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
; CHECK-ARM-NEXT: bx lr
;
; CHECK-T1-LABEL: cmn_nsw:
; CHECK-T1: @ %bb.0:
-; CHECK-T1-NEXT: rsbs r1, r1, #0
-; CHECK-T1-NEXT: cmp r0, r1
+; CHECK-T1-NEXT: cmn r0, r1
; CHECK-T1-NEXT: bgt .LBB49_2
; CHECK-T1-NEXT: @ %bb.1:
; CHECK-T1-NEXT: movs r0, #0
@@ -2018,12 +2016,11 @@ define i1 @cmn_nsw(i32 %a, i32 %b) {
;
; CHECK-T2-LABEL: cmn_nsw:
; CHECK-T2: @ %bb.0:
-; CHECK-T2-NEXT: rsbs r2, r1, #0
-; CHECK-T2-NEXT: movs r1, #0
-; CHECK-T2-NEXT: cmp r0, r2
+; CHECK-T2-NEXT: movs r2, #0
+; CHECK-T2-NEXT: cmn r0, r1
; CHECK-T2-NEXT: it gt
-; CHECK-T2-NEXT: movgt r1, #1
-; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: movgt r2, #1
+; CHECK-T2-NEXT: mov r0, r2
; CHECK-T2-NEXT: bx lr
%sub = sub nsw i32 0, %b
%cmp = icmp sgt i32 %a, %sub
@@ -2117,18 +2114,16 @@ define i1 @cmn_nsw_neg(i32 %a, i32 %b) {
define i1 @cmn_swap(i32 %a, i32 %b) {
; CHECK-ARM-LABEL: cmn_swap:
; CHECK-ARM: @ %bb.0:
-; CHECK-ARM-NEXT: rsb r2, r1, #0
-; CHECK-ARM-NEXT: mov r1, #0
-; CHECK-ARM-NEXT: cmp r2, r0
-; CHECK-ARM-NEXT: movwgt r1, #1
-; CHECK-ARM-NEXT: mov r0, r1
+; CHECK-ARM-NEXT: mov r2, #0
+; CHECK-ARM-NEXT: cmn r1, r0
+; CHECK-ARM-NEXT: movwlt r2, #1
+; CHECK-ARM-NEXT: mov r0, r2
; CHECK-ARM-NEXT: bx lr
;
; CHECK-T1-LABEL: cmn_swap:
; CHECK-T1: @ %bb.0:
-; CHECK-T1-NEXT: rsbs r1, r1, #0
-; CHECK-T1-NEXT: cmp r1, r0
-; CHECK-T1-NEXT: bgt .LBB52_2
+; CHECK-T1-NEXT: cmn r1, r0
+; CHECK-T1-NEXT: blt .LBB52_2
; CHECK-T1-NEXT: @ %bb.1:
; CHECK-T1-NEXT: movs r0, #0
; CHECK-T1-NEXT: bx lr
@@ -2138,12 +2133,11 @@ define i1 @cmn_swap(i32 %a, i32 %b) {
;
; CHECK-T2-LABEL: cmn_swap:
; CHECK-T2: @ %bb.0:
-; CHECK-T2-NEXT: rsbs r2, r1, #0
-; CHECK-T2-NEXT: movs r1, #0
-; CHECK-T2-NEXT: cmp r2, r0
-; CHECK-T2-NEXT: it gt
-; CHECK-T2-NEXT: movgt r1, #1
-; CHECK-T2-NEXT: mov r0, r1
+; CHECK-T2-NEXT: movs r2, #0
+; CHECK-T2-NEXT: cmn r1, r0
+; CHECK-T2-NEXT: it lt
+; CHECK-T2-NEXT: movlt r2, #1
+; CHECK-T2-NEXT: mov r0, r2
; CHECK-T2-NEXT: bx lr
%sub = sub nsw i32 0, %b
%cmp = icmp sgt i32 %sub, %a
diff --git a/llvm/test/MC/ARM/arm-shift-encoding.s b/llvm/test/MC/ARM/arm-shift-encoding.s
index 3c57b67f6e3ba..52a6f42942986 100644
--- a/llvm/test/MC/ARM/arm-shift-encoding.s
+++ b/llvm/test/MC/ARM/arm-shift-encoding.s
@@ -76,7 +76,7 @@
@ CHECK: str r9, [r10], r11 @ encoding: [0x0b,0x90,0x8a,0xe6]
@ Uses printSORegImmOperand(), used by ADCrsi ADDrsi ANDrsi BICrsi EORrsi
-@ ORRrsi RSBrsi RSCrsi SBCrsi SUBrsi CMNzrsi CMPrsi MOVsi MVNsi TEQrsi TSTrsi
+@ ORRrsi RSBrsi RSCrsi SBCrsi SUBrsi CMNrsi CMPrsi MOVsi MVNsi TEQrsi TSTrsi
adc sp, lr, pc
adc r1, r8, r9, lsr #32
diff --git a/llvm/test/MC/ARM/thumb-shift-encoding.s b/llvm/test/MC/ARM/thumb-shift-encoding.s
index ad35aff450556..6226e0204757c 100644
--- a/llvm/test/MC/ARM/thumb-shift-encoding.s
+++ b/llvm/test/MC/ARM/thumb-shift-encoding.s
@@ -1,7 +1,7 @@
@ RUN: llvm-mc -mcpu=cortex-a8 -triple thumbv7 -show-encoding < %s | FileCheck %s
@ Uses printT2SOOperand(), used by t2ADCrs t2ADDrs t2ANDrs t2BICrs t2EORrs
-@ t2ORNrs t2ORRrs t2RSBrs t2SBCrs t2SUBrs t2CMNzrs t2CMPrs t2MOVSsi t2MOVsi
+@ t2ORNrs t2ORRrs t2RSBrs t2SBCrs t2SUBrs t2CMNrs t2CMPrs t2MOVSsi t2MOVsi
@ t2MVNs t2TEQrs t2TSTrs
sbc.w r12, lr, r0
More information about the llvm-commits
mailing list