[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