[llvm] r349022 - [AArch64] Catch some more CMN opportunities.

Arnaud A. de Grandmaison via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 13 02:31:32 PST 2018


Author: aadg
Date: Thu Dec 13 02:31:32 2018
New Revision: 349022

URL: http://llvm.org/viewvc/llvm-project?rev=349022&view=rev
Log:
[AArch64] Catch some more CMN opportunities.

Fixes https://bugs.llvm.org/show_bug.cgi?id=33486

Added:
    llvm/trunk/test/CodeGen/AArch64/cmp-to-cmn.ll
Modified:
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp

Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=349022&r1=349021&r2=349022&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Thu Dec 13 02:31:32 2018
@@ -1520,6 +1520,11 @@ static SDValue emitComparison(SDValue LH
     // Can we combine a (CMP op1, (sub 0, op2) into a CMN instruction ?
     Opcode = AArch64ISD::ADDS;
     RHS = RHS.getOperand(1);
+  } else if (isCMN(LHS, CC)) {
+    // As we are looking for EQ/NE compares, the operands can be commuted ; can
+    // we combine a (CMP (sub 0, op1), op2) into a CMN instruction ?
+    Opcode = AArch64ISD::ADDS;
+    LHS = LHS.getOperand(1);
   } else if (LHS.getOpcode() == ISD::AND && isNullConstant(RHS) &&
              !isUnsignedIntSetCC(CC)) {
     // Similarly, (CMP (and X, Y), 0) can be implemented with a TST

Added: llvm/trunk/test/CodeGen/AArch64/cmp-to-cmn.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/cmp-to-cmn.ll?rev=349022&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/cmp-to-cmn.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/cmp-to-cmn.ll Thu Dec 13 02:31:32 2018
@@ -0,0 +1,399 @@
+; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "arm64"
+
+define i1 @test_EQ_IllEbT(i64 %a, i64 %b) {
+; CHECK-LABEL: test_EQ_IllEbT
+; CHECK:      cmn	x1, x0
+; CHECK-NEXT: cset	w0, eq
+; CHECK-NEXT: ret
+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-LABEL: test_EQ_IliEbT
+; CHECK:      cmn	x0, w1, sxtw
+; CHECK-NEXT: cset	w0, eq
+; CHECK-NEXT: ret
+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-LABEL: test_EQ_IlsEbT
+; CHECK:      cmn	x0, w1, sxth
+; CHECK-NEXT: cset	w0, eq
+; CHECK-NEXT: ret
+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-LABEL: test_EQ_IlcEbT
+; CHECK: 	cmn	x0, w1, uxtb
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT: 	ret
+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-LABEL: test_EQ_IilEbT
+; CHECK: 	cmn	x1, w0, sxtw
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT: 	ret
+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-LABEL: test_EQ_IiiEbT
+; CHECK: 	cmn	w1, w0
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT: 	ret
+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-LABEL: test_EQ_IisEbT
+; CHECK: 	cmn	w0, w1, sxth
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT: 	ret
+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-LABEL: test_EQ_IicEbT
+; CHECK: 	cmn	w0, w1, uxtb
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT: 	ret
+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-LABEL: test_EQ_IslEbT
+; CHECK: 	cmn	x1, w0, sxth
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT: 	ret
+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-LABEL: test_EQ_IsiEbT
+; CHECK: 	cmn	w1, w0, sxth
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT: 	ret
+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-LABEL: test_EQ_IssEbT
+; CHECK: 	sxth	w8, w1
+; CHECK-NEXT: 	cmn	w8, w0, sxth
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT;   ret
+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-LABEL: test_EQ_IscEbT
+; CHECK: 	and	w8, w1, #0xff
+; CHECK-NEXT: 	cmn	w8, w0, sxth
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT;   ret
+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-LABEL: test_EQ_IclEbT
+; CHECK:      	cmn	x1, w0, uxtb
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT: 	ret
+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-LABEL: test_EQ_IciEbT
+; CHECK:      	cmn	w1, w0, uxtb
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT: 	ret
+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-LABEL: test_EQ_IcsEbT
+; CHECK:      	sxth	w8, w1
+; CHECK-NEXT: 	cmn	w8, w0, uxtb
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT:	ret
+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-LABEL: test_EQ_IccEbT
+; CHECK:      	and	w8, w1, #0xff
+; CHECK-NEXT: 	cmn	w8, w0, uxtb
+; CHECK-NEXT: 	cset	w0, eq
+; CHECK-NEXT:	ret
+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-LABEL: test_NE_IllEbT
+; CHECK:      	cmn	x1, x0
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL: test_NE_IliEbT
+; CHECK:      	cmn	x0, w1, sxtw
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL: test_NE_IlsEbT
+; CHECK:      	cmn	x0, w1, sxth
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL: test_NE_IlcEbT
+; CHECK:      	cmn	x0, w1, uxtb
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL: test_NE_IilEbT
+; CHECK:      	cmn	x1, w0, sxtw
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL: test_NE_IiiEbT
+; CHECK:      	cmn	w1, w0
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL: test_NE_IisEbT
+; CHECK:      	cmn	w0, w1, sxth
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL: test_NE_IicEbT
+; CHECK:      	cmn	w0, w1, uxtb
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL: test_NE_IslEbT
+; CHECK:      	cmn	x1, w0, sxth
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL: test_NE_IsiEbT
+; CHECK:      	cmn	w1, w0, sxth
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL:test_NE_IssEbT
+; CHECK:      	sxth	w8, w1
+; CHECK-NEXT: 	cmn	w8, w0, sxth
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT:	ret
+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-LABEL:test_NE_IscEbT
+; CHECK:      	and	w8, w1, #0xff
+; CHECK-NEXT: 	cmn	w8, w0, sxth
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT:	ret
+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-LABEL:test_NE_IclEbT
+; CHECK:      	cmn	x1, w0, uxtb
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL:test_NE_IciEbT
+; CHECK:      	cmn	w1, w0, uxtb
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT: 	ret
+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-LABEL:test_NE_IcsEbT
+; CHECK:      	sxth	w8, w1
+; CHECK-NEXT: 	cmn	w8, w0, uxtb
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT:	ret
+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-LABEL:test_NE_IccEbT
+; CHECK:      	and	w8, w1, #0xff
+; CHECK-NEXT: 	cmn	w8, w0, uxtb
+; CHECK-NEXT: 	cset	w0, ne
+; CHECK-NEXT:	ret
+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
+}




More information about the llvm-commits mailing list