[llvm] [InstCombine] Fold (sub (xor X, (sext C)), (sext C)) => (select C (neg X), X) (PR #79417)
Kai Luo via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 28 21:37:45 PST 2024
https://github.com/bzEq updated https://github.com/llvm/llvm-project/pull/79417
>From 85360d691b8572a1f2d6e42f11dd2694b194507a Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Thu, 25 Jan 2024 07:48:50 +0000
Subject: [PATCH 01/14] Add test
---
llvm/test/CodeGen/AArch64/absdiff.ll | 18 +++++++++++++++
llvm/test/CodeGen/PowerPC/absdiff.ll | 19 ++++++++++++++++
llvm/test/CodeGen/X86/absdiff.ll | 22 +++++++++++++++++++
.../Transforms/InstCombine/sub-xor-cmp.ll | 20 +++++++++++++++++
4 files changed, 79 insertions(+)
create mode 100644 llvm/test/CodeGen/AArch64/absdiff.ll
create mode 100644 llvm/test/CodeGen/PowerPC/absdiff.ll
create mode 100644 llvm/test/CodeGen/X86/absdiff.ll
create mode 100644 llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
diff --git a/llvm/test/CodeGen/AArch64/absdiff.ll b/llvm/test/CodeGen/AArch64/absdiff.ll
new file mode 100644
index 00000000000000..ca7b5a583cbe51
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/absdiff.ll
@@ -0,0 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -mtriple=aarch64-linux-gnu -passes=instcombine < %s -o - | llc -mtriple=aarch64-linux-gnu -o - | FileCheck %s
+
+define i64 @absdiff(i64 %0, i64 %1) {
+; CHECK-LABEL: absdiff:
+; CHECK: // %bb.0:
+; CHECK-NEXT: subs x8, x0, x1
+; CHECK-NEXT: csetm x9, lo
+; CHECK-NEXT: cinv x8, x8, lo
+; CHECK-NEXT: sub x0, x8, x9
+; CHECK-NEXT: ret
+ %3 = icmp ult i64 %0, %1
+ %4 = sext i1 %3 to i64
+ %5 = sub i64 %0, %1
+ %6 = xor i64 %5, %4
+ %7 = sub i64 %6, %4
+ ret i64 %7
+}
diff --git a/llvm/test/CodeGen/PowerPC/absdiff.ll b/llvm/test/CodeGen/PowerPC/absdiff.ll
new file mode 100644
index 00000000000000..a26482fc6497b8
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/absdiff.ll
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -mtriple=powerpc64-linux-gnu -passes=instcombine < %s -o - | llc -mtriple=powerpc64-linux-gnu -o - | FileCheck %s
+
+define i64 @absdiff(i64 %0, i64 %1) {
+; CHECK-LABEL: absdiff:
+; CHECK: # %bb.0:
+; CHECK-NEXT: subc 5, 3, 4
+; CHECK-NEXT: subfe 5, 3, 3
+; CHECK-NEXT: sub 3, 3, 4
+; CHECK-NEXT: xor 3, 3, 5
+; CHECK-NEXT: sub 3, 3, 5
+; CHECK-NEXT: blr
+ %3 = icmp ult i64 %0, %1
+ %4 = sext i1 %3 to i64
+ %5 = sub i64 %0, %1
+ %6 = xor i64 %5, %4
+ %7 = sub i64 %6, %4
+ ret i64 %7
+}
diff --git a/llvm/test/CodeGen/X86/absdiff.ll b/llvm/test/CodeGen/X86/absdiff.ll
new file mode 100644
index 00000000000000..46c7b62e43685b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/absdiff.ll
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -mtriple=x86_64-linux-gnu -passes=instcombine < %s -o - | llc -mtriple=x86_64-linux-gnu -o - | FileCheck %s
+
+define i64 @absdiff(i64 %0, i64 %1) {
+; CHECK-LABEL: absdiff:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: movq %rdi, %rcx
+; CHECK-NEXT: subq %rsi, %rcx
+; CHECK-NEXT: setb %al
+; CHECK-NEXT: negq %rax
+; CHECK-NEXT: xorq %rcx, %rax
+; CHECK-NEXT: cmpq %rsi, %rdi
+; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: retq
+ %3 = icmp ult i64 %0, %1
+ %4 = sext i1 %3 to i64
+ %5 = sub i64 %0, %1
+ %6 = xor i64 %5, %4
+ %7 = sub i64 %6, %4
+ ret i64 %7
+}
diff --git a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
new file mode 100644
index 00000000000000..0555bc1c365f5a
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i64 @absdiff(i64 %0, i64 %1) {
+; CHECK-LABEL: define i64 @absdiff(
+; CHECK-SAME: i64 [[TMP0:%.*]], i64 [[TMP1:%.*]]) {
+; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP0]], [[TMP1]]
+; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[TMP3]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = sub i64 [[TMP0]], [[TMP1]]
+; CHECK-NEXT: [[TMP6:%.*]] = xor i64 [[TMP5]], [[TMP4]]
+; CHECK-NEXT: [[TMP7:%.*]] = sub i64 [[TMP6]], [[TMP4]]
+; CHECK-NEXT: ret i64 [[TMP7]]
+;
+ %3 = icmp ult i64 %0, %1
+ %4 = sext i1 %3 to i64
+ %5 = sub i64 %0, %1
+ %6 = xor i64 %5, %4
+ %7 = sub i64 %6, %4
+ ret i64 %7
+}
>From 9073811a3b45c6bee911f5af4ec3f9debd09f62f Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Thu, 25 Jan 2024 06:45:33 +0000
Subject: [PATCH 02/14] (sub (xor X, (sext C)), (sext C)) => (select C (neg X),
X)
---
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 8a00b75a1f7404..1a13fa4e209994 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2448,6 +2448,16 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
}
}
+ {
+ // (sub (xor X, (sext C)), (sext C)) => (select C (neg X), X)
+ Value *C0, *C1, *X;
+ if (match(Op0, m_Xor(m_Value(X), m_SExt(m_Value(C0)))) &&
+ (C0->getType()->getScalarSizeInBits() == 1) &&
+ match(Op1, m_SExt(m_Value(C1))) && (C0 == C1)) {
+ return SelectInst::Create(C0, Builder.CreateNeg(X), X);
+ }
+ }
+
if (Instruction *R = tryFoldInstWithCtpopWithNot(&I))
return R;
>From 6ef247174203d4a47e16ed5648fbfade3284ecff Mon Sep 17 00:00:00 2001
From: Kai Luo <lkail at cn.ibm.com>
Date: Thu, 25 Jan 2024 07:52:14 +0000
Subject: [PATCH 03/14] Update test
---
llvm/test/CodeGen/AArch64/absdiff.ll | 4 +---
llvm/test/CodeGen/PowerPC/absdiff.ll | 14 +++++++++-----
llvm/test/CodeGen/X86/absdiff.ll | 11 ++++-------
llvm/test/Transforms/InstCombine/sub-xor-cmp.ll | 9 ++++-----
4 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/absdiff.ll b/llvm/test/CodeGen/AArch64/absdiff.ll
index ca7b5a583cbe51..88c6fdad0a2030 100644
--- a/llvm/test/CodeGen/AArch64/absdiff.ll
+++ b/llvm/test/CodeGen/AArch64/absdiff.ll
@@ -5,9 +5,7 @@ define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: absdiff:
; CHECK: // %bb.0:
; CHECK-NEXT: subs x8, x0, x1
-; CHECK-NEXT: csetm x9, lo
-; CHECK-NEXT: cinv x8, x8, lo
-; CHECK-NEXT: sub x0, x8, x9
+; CHECK-NEXT: cneg x0, x8, lo
; CHECK-NEXT: ret
%3 = icmp ult i64 %0, %1
%4 = sext i1 %3 to i64
diff --git a/llvm/test/CodeGen/PowerPC/absdiff.ll b/llvm/test/CodeGen/PowerPC/absdiff.ll
index a26482fc6497b8..c806da988f0a0b 100644
--- a/llvm/test/CodeGen/PowerPC/absdiff.ll
+++ b/llvm/test/CodeGen/PowerPC/absdiff.ll
@@ -4,11 +4,15 @@
define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: absdiff:
; CHECK: # %bb.0:
-; CHECK-NEXT: subc 5, 3, 4
-; CHECK-NEXT: subfe 5, 3, 3
-; CHECK-NEXT: sub 3, 3, 4
-; CHECK-NEXT: xor 3, 3, 5
-; CHECK-NEXT: sub 3, 3, 5
+; CHECK-NEXT: sub 5, 3, 4
+; CHECK-NEXT: neg 6, 5
+; CHECK-NEXT: cmpld 3, 4
+; CHECK-NEXT: bc 12, 0, .LBB0_2
+; CHECK-NEXT: # %bb.1:
+; CHECK-NEXT: ori 3, 5, 0
+; CHECK-NEXT: blr
+; CHECK-NEXT: .LBB0_2:
+; CHECK-NEXT: addi 3, 6, 0
; CHECK-NEXT: blr
%3 = icmp ult i64 %0, %1
%4 = sext i1 %3 to i64
diff --git a/llvm/test/CodeGen/X86/absdiff.ll b/llvm/test/CodeGen/X86/absdiff.ll
index 46c7b62e43685b..ce9a0093544813 100644
--- a/llvm/test/CodeGen/X86/absdiff.ll
+++ b/llvm/test/CodeGen/X86/absdiff.ll
@@ -4,14 +4,11 @@
define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: absdiff:
; CHECK: # %bb.0:
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: movq %rdi, %rcx
-; CHECK-NEXT: subq %rsi, %rcx
-; CHECK-NEXT: setb %al
+; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: subq %rsi, %rax
; CHECK-NEXT: negq %rax
-; CHECK-NEXT: xorq %rcx, %rax
-; CHECK-NEXT: cmpq %rsi, %rdi
-; CHECK-NEXT: adcq $0, %rax
+; CHECK-NEXT: subq %rsi, %rdi
+; CHECK-NEXT: cmovaeq %rdi, %rax
; CHECK-NEXT: retq
%3 = icmp ult i64 %0, %1
%4 = sext i1 %3 to i64
diff --git a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
index 0555bc1c365f5a..393f2bd45bb8d7 100644
--- a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
+++ b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
@@ -5,11 +5,10 @@ define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: define i64 @absdiff(
; CHECK-SAME: i64 [[TMP0:%.*]], i64 [[TMP1:%.*]]) {
; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP0]], [[TMP1]]
-; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[TMP3]] to i64
-; CHECK-NEXT: [[TMP5:%.*]] = sub i64 [[TMP0]], [[TMP1]]
-; CHECK-NEXT: [[TMP6:%.*]] = xor i64 [[TMP5]], [[TMP4]]
-; CHECK-NEXT: [[TMP7:%.*]] = sub i64 [[TMP6]], [[TMP4]]
-; CHECK-NEXT: ret i64 [[TMP7]]
+; CHECK-NEXT: [[TMP4:%.*]] = sub i64 [[TMP0]], [[TMP1]]
+; CHECK-NEXT: [[TMP5:%.*]] = sub i64 0, [[TMP4]]
+; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[TMP3]], i64 [[TMP5]], i64 [[TMP4]]
+; CHECK-NEXT: ret i64 [[TMP6]]
;
%3 = icmp ult i64 %0, %1
%4 = sext i1 %3 to i64
>From cb8c375ed2f7385470f8a096cf920c71ae6267e3 Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Fri, 26 Jan 2024 13:06:37 +0800
Subject: [PATCH 04/14] Add codegen comparison
---
llvm/test/CodeGen/AArch64/absdiff.ll | 35 +++++++++++++++++++++--
llvm/test/CodeGen/PowerPC/absdiff.ll | 42 ++++++++++++++++++++++++++--
llvm/test/CodeGen/X86/absdiff.ll | 39 ++++++++++++++++++++++++--
3 files changed, 108 insertions(+), 8 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/absdiff.ll b/llvm/test/CodeGen/AArch64/absdiff.ll
index 88c6fdad0a2030..0c6677c619d680 100644
--- a/llvm/test/CodeGen/AArch64/absdiff.ll
+++ b/llvm/test/CodeGen/AArch64/absdiff.ll
@@ -1,11 +1,27 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: opt -mtriple=aarch64-linux-gnu -passes=instcombine < %s -o - | llc -mtriple=aarch64-linux-gnu -o - | FileCheck %s
+; RUN: llc -mtriple=aarch64-linux-gnu -o - | FileCheck %s
-define i64 @absdiff(i64 %0, i64 %1) {
+define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: absdiff:
; CHECK: // %bb.0:
+; CHECK-NEXT: sub x8, x1, x0
+; CHECK-NEXT: subs x9, x0, x1
+; CHECK-NEXT: csel x0, x8, x9, lo
+; CHECK-NEXT: ret
+ %3 = icmp ult i64 %0, %1
+ %4 = sub i64 %0, %1
+ %5 = sub i64 %1, %0
+ %6 = select i1 %3, i64 %5, i64 %4
+ ret i64 %6
+}
+
+define i64 @absdiff1(i64 %0, i64 %1) {
+; CHECK-LABEL: absdiff1:
+; CHECK: // %bb.0:
; CHECK-NEXT: subs x8, x0, x1
-; CHECK-NEXT: cneg x0, x8, lo
+; CHECK-NEXT: csetm x9, lo
+; CHECK-NEXT: cinv x8, x8, lo
+; CHECK-NEXT: sub x0, x8, x9
; CHECK-NEXT: ret
%3 = icmp ult i64 %0, %1
%4 = sext i1 %3 to i64
@@ -14,3 +30,16 @@ define i64 @absdiff(i64 %0, i64 %1) {
%7 = sub i64 %6, %4
ret i64 %7
}
+
+define i64 @absdiff2(i64 %0, i64 %1) {
+; CHECK-LABEL: absdiff2:
+; CHECK: // %bb.0:
+; CHECK-NEXT: subs x8, x0, x1
+; CHECK-NEXT: cneg x0, x8, lo
+; CHECK-NEXT: ret
+ %3 = icmp ult i64 %0, %1
+ %4 = sub i64 %0, %1
+ %5 = sub i64 0, %4
+ %6 = select i1 %3, i64 %5, i64 %4
+ ret i64 %6
+}
diff --git a/llvm/test/CodeGen/PowerPC/absdiff.ll b/llvm/test/CodeGen/PowerPC/absdiff.ll
index c806da988f0a0b..a0959e5908241b 100644
--- a/llvm/test/CodeGen/PowerPC/absdiff.ll
+++ b/llvm/test/CodeGen/PowerPC/absdiff.ll
@@ -1,11 +1,11 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: opt -mtriple=powerpc64-linux-gnu -passes=instcombine < %s -o - | llc -mtriple=powerpc64-linux-gnu -o - | FileCheck %s
+; RUN: llc -mtriple=powerpc64-linux-gnu -o - | FileCheck %s
-define i64 @absdiff(i64 %0, i64 %1) {
+define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: absdiff:
; CHECK: # %bb.0:
; CHECK-NEXT: sub 5, 3, 4
-; CHECK-NEXT: neg 6, 5
+; CHECK-NEXT: sub 6, 4, 3
; CHECK-NEXT: cmpld 3, 4
; CHECK-NEXT: bc 12, 0, .LBB0_2
; CHECK-NEXT: # %bb.1:
@@ -13,6 +13,22 @@ define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-NEXT: blr
; CHECK-NEXT: .LBB0_2:
; CHECK-NEXT: addi 3, 6, 0
+; CHECK-NEXT: blr
+ %3 = icmp ult i64 %0, %1
+ %4 = sub i64 %0, %1
+ %5 = sub i64 %1, %0
+ %6 = select i1 %3, i64 %5, i64 %4
+ ret i64 %6
+}
+
+define i64 @absdiff1(i64 %0, i64 %1) {
+; CHECK-LABEL: absdiff1:
+; CHECK: # %bb.0:
+; CHECK-NEXT: subc 5, 3, 4
+; CHECK-NEXT: subfe 5, 3, 3
+; CHECK-NEXT: sub 3, 3, 4
+; CHECK-NEXT: xor 3, 3, 5
+; CHECK-NEXT: sub 3, 3, 5
; CHECK-NEXT: blr
%3 = icmp ult i64 %0, %1
%4 = sext i1 %3 to i64
@@ -21,3 +37,23 @@ define i64 @absdiff(i64 %0, i64 %1) {
%7 = sub i64 %6, %4
ret i64 %7
}
+
+define i64 @absdiff2(i64 %0, i64 %1) {
+; CHECK-LABEL: absdiff2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: sub 5, 3, 4
+; CHECK-NEXT: neg 6, 5
+; CHECK-NEXT: cmpld 3, 4
+; CHECK-NEXT: bc 12, 0, .LBB2_2
+; CHECK-NEXT: # %bb.1:
+; CHECK-NEXT: ori 3, 5, 0
+; CHECK-NEXT: blr
+; CHECK-NEXT: .LBB2_2:
+; CHECK-NEXT: addi 3, 6, 0
+; CHECK-NEXT: blr
+ %3 = icmp ult i64 %0, %1
+ %4 = sub i64 %0, %1
+ %5 = sub i64 0, %4
+ %6 = select i1 %3, i64 %5, i64 %4
+ ret i64 %6
+}
diff --git a/llvm/test/CodeGen/X86/absdiff.ll b/llvm/test/CodeGen/X86/absdiff.ll
index ce9a0093544813..cabb3628f369c4 100644
--- a/llvm/test/CodeGen/X86/absdiff.ll
+++ b/llvm/test/CodeGen/X86/absdiff.ll
@@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: opt -mtriple=x86_64-linux-gnu -passes=instcombine < %s -o - | llc -mtriple=x86_64-linux-gnu -o - | FileCheck %s
+; RUN: llc -mtriple=x86_64-linux-gnu -o - | FileCheck %s
-define i64 @absdiff(i64 %0, i64 %1) {
+define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: absdiff:
; CHECK: # %bb.0:
; CHECK-NEXT: movq %rdi, %rax
@@ -9,6 +9,25 @@ define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-NEXT: negq %rax
; CHECK-NEXT: subq %rsi, %rdi
; CHECK-NEXT: cmovaeq %rdi, %rax
+; CHECK-NEXT: retq
+ %3 = icmp ult i64 %0, %1
+ %4 = sub i64 %0, %1
+ %5 = sub i64 %1, %0
+ %6 = select i1 %3, i64 %5, i64 %4
+ ret i64 %6
+}
+
+define i64 @absdiff1(i64 %0, i64 %1) {
+; CHECK-LABEL: absdiff1:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: movq %rdi, %rcx
+; CHECK-NEXT: subq %rsi, %rcx
+; CHECK-NEXT: setb %al
+; CHECK-NEXT: negq %rax
+; CHECK-NEXT: xorq %rcx, %rax
+; CHECK-NEXT: cmpq %rsi, %rdi
+; CHECK-NEXT: adcq $0, %rax
; CHECK-NEXT: retq
%3 = icmp ult i64 %0, %1
%4 = sext i1 %3 to i64
@@ -17,3 +36,19 @@ define i64 @absdiff(i64 %0, i64 %1) {
%7 = sub i64 %6, %4
ret i64 %7
}
+
+define i64 @absdiff2(i64 %0, i64 %1) {
+; CHECK-LABEL: absdiff2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movq %rdi, %rax
+; CHECK-NEXT: subq %rsi, %rax
+; CHECK-NEXT: negq %rax
+; CHECK-NEXT: subq %rsi, %rdi
+; CHECK-NEXT: cmovaeq %rdi, %rax
+; CHECK-NEXT: retq
+ %3 = icmp ult i64 %0, %1
+ %4 = sub i64 %0, %1
+ %5 = sub i64 0, %4
+ %6 = select i1 %3, i64 %5, i64 %4
+ ret i64 %6
+}
>From 80ef5c90038ecc1837a620f227933cd642e366b0 Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Fri, 26 Jan 2024 13:30:42 +0800
Subject: [PATCH 05/14] Fix test
---
llvm/test/CodeGen/AArch64/absdiff.ll | 2 +-
llvm/test/CodeGen/PowerPC/absdiff.ll | 2 +-
llvm/test/CodeGen/X86/absdiff.ll | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/absdiff.ll b/llvm/test/CodeGen/AArch64/absdiff.ll
index 0c6677c619d680..3d2221e509a41f 100644
--- a/llvm/test/CodeGen/AArch64/absdiff.ll
+++ b/llvm/test/CodeGen/AArch64/absdiff.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: llc -mtriple=aarch64-linux-gnu -o - | FileCheck %s
+; RUN: llc -mtriple=aarch64-linux-gnu -o - < %s | FileCheck %s
define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: absdiff:
diff --git a/llvm/test/CodeGen/PowerPC/absdiff.ll b/llvm/test/CodeGen/PowerPC/absdiff.ll
index a0959e5908241b..2940ace3866b4d 100644
--- a/llvm/test/CodeGen/PowerPC/absdiff.ll
+++ b/llvm/test/CodeGen/PowerPC/absdiff.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: llc -mtriple=powerpc64-linux-gnu -o - | FileCheck %s
+; RUN: llc -mtriple=powerpc64-linux-gnu -o - < %s | FileCheck %s
define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: absdiff:
diff --git a/llvm/test/CodeGen/X86/absdiff.ll b/llvm/test/CodeGen/X86/absdiff.ll
index cabb3628f369c4..0f7e66237676c0 100644
--- a/llvm/test/CodeGen/X86/absdiff.ll
+++ b/llvm/test/CodeGen/X86/absdiff.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: llc -mtriple=x86_64-linux-gnu -o - | FileCheck %s
+; RUN: llc -mtriple=x86_64-linux-gnu -o - < %s | FileCheck %s
define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: absdiff:
>From d0c3f9f5a5aac4b17db992c085401551ec7e7428 Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Fri, 26 Jan 2024 14:39:42 +0800
Subject: [PATCH 06/14] Removed codegen tests
---
llvm/test/CodeGen/AArch64/absdiff.ll | 45 ---------------------
llvm/test/CodeGen/PowerPC/absdiff.ll | 59 ----------------------------
llvm/test/CodeGen/X86/absdiff.ll | 54 -------------------------
3 files changed, 158 deletions(-)
delete mode 100644 llvm/test/CodeGen/AArch64/absdiff.ll
delete mode 100644 llvm/test/CodeGen/PowerPC/absdiff.ll
delete mode 100644 llvm/test/CodeGen/X86/absdiff.ll
diff --git a/llvm/test/CodeGen/AArch64/absdiff.ll b/llvm/test/CodeGen/AArch64/absdiff.ll
deleted file mode 100644
index 3d2221e509a41f..00000000000000
--- a/llvm/test/CodeGen/AArch64/absdiff.ll
+++ /dev/null
@@ -1,45 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: llc -mtriple=aarch64-linux-gnu -o - < %s | FileCheck %s
-
-define i64 @absdiff(i64 %0, i64 %1) {
-; CHECK-LABEL: absdiff:
-; CHECK: // %bb.0:
-; CHECK-NEXT: sub x8, x1, x0
-; CHECK-NEXT: subs x9, x0, x1
-; CHECK-NEXT: csel x0, x8, x9, lo
-; CHECK-NEXT: ret
- %3 = icmp ult i64 %0, %1
- %4 = sub i64 %0, %1
- %5 = sub i64 %1, %0
- %6 = select i1 %3, i64 %5, i64 %4
- ret i64 %6
-}
-
-define i64 @absdiff1(i64 %0, i64 %1) {
-; CHECK-LABEL: absdiff1:
-; CHECK: // %bb.0:
-; CHECK-NEXT: subs x8, x0, x1
-; CHECK-NEXT: csetm x9, lo
-; CHECK-NEXT: cinv x8, x8, lo
-; CHECK-NEXT: sub x0, x8, x9
-; CHECK-NEXT: ret
- %3 = icmp ult i64 %0, %1
- %4 = sext i1 %3 to i64
- %5 = sub i64 %0, %1
- %6 = xor i64 %5, %4
- %7 = sub i64 %6, %4
- ret i64 %7
-}
-
-define i64 @absdiff2(i64 %0, i64 %1) {
-; CHECK-LABEL: absdiff2:
-; CHECK: // %bb.0:
-; CHECK-NEXT: subs x8, x0, x1
-; CHECK-NEXT: cneg x0, x8, lo
-; CHECK-NEXT: ret
- %3 = icmp ult i64 %0, %1
- %4 = sub i64 %0, %1
- %5 = sub i64 0, %4
- %6 = select i1 %3, i64 %5, i64 %4
- ret i64 %6
-}
diff --git a/llvm/test/CodeGen/PowerPC/absdiff.ll b/llvm/test/CodeGen/PowerPC/absdiff.ll
deleted file mode 100644
index 2940ace3866b4d..00000000000000
--- a/llvm/test/CodeGen/PowerPC/absdiff.ll
+++ /dev/null
@@ -1,59 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: llc -mtriple=powerpc64-linux-gnu -o - < %s | FileCheck %s
-
-define i64 @absdiff(i64 %0, i64 %1) {
-; CHECK-LABEL: absdiff:
-; CHECK: # %bb.0:
-; CHECK-NEXT: sub 5, 3, 4
-; CHECK-NEXT: sub 6, 4, 3
-; CHECK-NEXT: cmpld 3, 4
-; CHECK-NEXT: bc 12, 0, .LBB0_2
-; CHECK-NEXT: # %bb.1:
-; CHECK-NEXT: ori 3, 5, 0
-; CHECK-NEXT: blr
-; CHECK-NEXT: .LBB0_2:
-; CHECK-NEXT: addi 3, 6, 0
-; CHECK-NEXT: blr
- %3 = icmp ult i64 %0, %1
- %4 = sub i64 %0, %1
- %5 = sub i64 %1, %0
- %6 = select i1 %3, i64 %5, i64 %4
- ret i64 %6
-}
-
-define i64 @absdiff1(i64 %0, i64 %1) {
-; CHECK-LABEL: absdiff1:
-; CHECK: # %bb.0:
-; CHECK-NEXT: subc 5, 3, 4
-; CHECK-NEXT: subfe 5, 3, 3
-; CHECK-NEXT: sub 3, 3, 4
-; CHECK-NEXT: xor 3, 3, 5
-; CHECK-NEXT: sub 3, 3, 5
-; CHECK-NEXT: blr
- %3 = icmp ult i64 %0, %1
- %4 = sext i1 %3 to i64
- %5 = sub i64 %0, %1
- %6 = xor i64 %5, %4
- %7 = sub i64 %6, %4
- ret i64 %7
-}
-
-define i64 @absdiff2(i64 %0, i64 %1) {
-; CHECK-LABEL: absdiff2:
-; CHECK: # %bb.0:
-; CHECK-NEXT: sub 5, 3, 4
-; CHECK-NEXT: neg 6, 5
-; CHECK-NEXT: cmpld 3, 4
-; CHECK-NEXT: bc 12, 0, .LBB2_2
-; CHECK-NEXT: # %bb.1:
-; CHECK-NEXT: ori 3, 5, 0
-; CHECK-NEXT: blr
-; CHECK-NEXT: .LBB2_2:
-; CHECK-NEXT: addi 3, 6, 0
-; CHECK-NEXT: blr
- %3 = icmp ult i64 %0, %1
- %4 = sub i64 %0, %1
- %5 = sub i64 0, %4
- %6 = select i1 %3, i64 %5, i64 %4
- ret i64 %6
-}
diff --git a/llvm/test/CodeGen/X86/absdiff.ll b/llvm/test/CodeGen/X86/absdiff.ll
deleted file mode 100644
index 0f7e66237676c0..00000000000000
--- a/llvm/test/CodeGen/X86/absdiff.ll
+++ /dev/null
@@ -1,54 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: llc -mtriple=x86_64-linux-gnu -o - < %s | FileCheck %s
-
-define i64 @absdiff(i64 %0, i64 %1) {
-; CHECK-LABEL: absdiff:
-; CHECK: # %bb.0:
-; CHECK-NEXT: movq %rdi, %rax
-; CHECK-NEXT: subq %rsi, %rax
-; CHECK-NEXT: negq %rax
-; CHECK-NEXT: subq %rsi, %rdi
-; CHECK-NEXT: cmovaeq %rdi, %rax
-; CHECK-NEXT: retq
- %3 = icmp ult i64 %0, %1
- %4 = sub i64 %0, %1
- %5 = sub i64 %1, %0
- %6 = select i1 %3, i64 %5, i64 %4
- ret i64 %6
-}
-
-define i64 @absdiff1(i64 %0, i64 %1) {
-; CHECK-LABEL: absdiff1:
-; CHECK: # %bb.0:
-; CHECK-NEXT: xorl %eax, %eax
-; CHECK-NEXT: movq %rdi, %rcx
-; CHECK-NEXT: subq %rsi, %rcx
-; CHECK-NEXT: setb %al
-; CHECK-NEXT: negq %rax
-; CHECK-NEXT: xorq %rcx, %rax
-; CHECK-NEXT: cmpq %rsi, %rdi
-; CHECK-NEXT: adcq $0, %rax
-; CHECK-NEXT: retq
- %3 = icmp ult i64 %0, %1
- %4 = sext i1 %3 to i64
- %5 = sub i64 %0, %1
- %6 = xor i64 %5, %4
- %7 = sub i64 %6, %4
- ret i64 %7
-}
-
-define i64 @absdiff2(i64 %0, i64 %1) {
-; CHECK-LABEL: absdiff2:
-; CHECK: # %bb.0:
-; CHECK-NEXT: movq %rdi, %rax
-; CHECK-NEXT: subq %rsi, %rax
-; CHECK-NEXT: negq %rax
-; CHECK-NEXT: subq %rsi, %rdi
-; CHECK-NEXT: cmovaeq %rdi, %rax
-; CHECK-NEXT: retq
- %3 = icmp ult i64 %0, %1
- %4 = sub i64 %0, %1
- %5 = sub i64 0, %4
- %6 = select i1 %3, i64 %5, i64 %4
- ret i64 %6
-}
>From 0c71172003af88c227db2b04a577094103a1ddb0 Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Fri, 26 Jan 2024 14:46:42 +0800
Subject: [PATCH 07/14] Update
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
Co-authored-by: Yingwei Zheng <dtcxzyw at qq.com>
---
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 1a13fa4e209994..31b1083737f94e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2453,7 +2453,7 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
Value *C0, *C1, *X;
if (match(Op0, m_Xor(m_Value(X), m_SExt(m_Value(C0)))) &&
(C0->getType()->getScalarSizeInBits() == 1) &&
- match(Op1, m_SExt(m_Value(C1))) && (C0 == C1)) {
+ match(Op1, m_SExt(m_Specific(C0)))) {
return SelectInst::Create(C0, Builder.CreateNeg(X), X);
}
}
>From 8a5f5d72ee30c7e71da0c1769ae5493ee1d3c7b0 Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Fri, 26 Jan 2024 15:48:04 +0800
Subject: [PATCH 08/14] Up
---
.../InstCombine/InstCombineAddSub.cpp | 17 +++++++----
.../Transforms/InstCombine/sub-xor-cmp.ll | 28 +++++++++++++++++++
2 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 31b1083737f94e..39f11c073aa662 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2449,13 +2449,18 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
}
{
- // (sub (xor X, (sext C)), (sext C)) => (select C (neg X), X)
- Value *C0, *C1, *X;
- if (match(Op0, m_Xor(m_Value(X), m_SExt(m_Value(C0)))) &&
- (C0->getType()->getScalarSizeInBits() == 1) &&
- match(Op1, m_SExt(m_Specific(C0)))) {
+ // (sub (xor X, (sext C)), (sext C)) => (select C, (neg X), X)
+ // (sub (sext C), (xor X, (sext C))) => (select C, X, (neg X))
+ Value *C0, *X;
+ auto m_SubXorSext = [&C0, &X](Value *LHS, Value *RHS) {
+ return match(LHS, m_Xor(m_Value(X), m_SExt(m_OneUse(m_Value(C0))))) &&
+ (C0->getType()->getScalarSizeInBits() == 1) &&
+ match(RHS, m_SExt(m_Specific(C0)));
+ };
+ if (m_SubXorSext(Op0, Op1))
return SelectInst::Create(C0, Builder.CreateNeg(X), X);
- }
+ if (m_SubXorSext(Op1, Op0))
+ return SelectInst::Create(C0, X, Builder.CreateNeg(X));
}
if (Instruction *R = tryFoldInstWithCtpopWithNot(&I))
diff --git a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
index 393f2bd45bb8d7..0ed202d7cd86fb 100644
--- a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
+++ b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
@@ -1,6 +1,34 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+define i64 @foo(i64 %a, i1 %b) {
+; CHECK-LABEL: define i64 @foo(
+; CHECK-SAME: i64 [[A:%.*]], i1 [[B:%.*]]) {
+; CHECK-NEXT: [[C:%.*]] = sext i1 [[B]] to i64
+; CHECK-NEXT: [[D:%.*]] = xor i64 [[C]], [[A]]
+; CHECK-NEXT: [[R:%.*]] = sub i64 [[D]], [[C]]
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %c = sext i1 %b to i64
+ %d = xor i64 %a, %c
+ %r = sub i64 %d, %c
+ ret i64 %r
+}
+
+define i64 @bar(i64 %a, i1 %b) {
+; CHECK-LABEL: define i64 @bar(
+; CHECK-SAME: i64 [[A:%.*]], i1 [[B:%.*]]) {
+; CHECK-NEXT: [[C:%.*]] = sext i1 [[B]] to i64
+; CHECK-NEXT: [[D:%.*]] = xor i64 [[C]], [[A]]
+; CHECK-NEXT: [[R:%.*]] = sub i64 [[C]], [[D]]
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %c = sext i1 %b to i64
+ %d = xor i64 %a, %c
+ %r = sub i64 %c, %d
+ ret i64 %r
+}
+
define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: define i64 @absdiff(
; CHECK-SAME: i64 [[TMP0:%.*]], i64 [[TMP1:%.*]]) {
>From 2af8703620fdd495ab22d6039ec95e52ff00d932 Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Fri, 26 Jan 2024 15:55:57 +0800
Subject: [PATCH 09/14] Up
---
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 2 +-
llvm/test/Transforms/InstCombine/sub-xor-cmp.ll | 10 ++++------
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 39f11c073aa662..b4158e240b89cd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2453,7 +2453,7 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
// (sub (sext C), (xor X, (sext C))) => (select C, X, (neg X))
Value *C0, *X;
auto m_SubXorSext = [&C0, &X](Value *LHS, Value *RHS) {
- return match(LHS, m_Xor(m_Value(X), m_SExt(m_OneUse(m_Value(C0))))) &&
+ return match(LHS, m_c_Xor(m_Value(X), m_SExt(m_OneUse(m_Value(C0))))) &&
(C0->getType()->getScalarSizeInBits() == 1) &&
match(RHS, m_SExt(m_Specific(C0)));
};
diff --git a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
index 0ed202d7cd86fb..2c1c0b4f7207a4 100644
--- a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
+++ b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
@@ -4,9 +4,8 @@
define i64 @foo(i64 %a, i1 %b) {
; CHECK-LABEL: define i64 @foo(
; CHECK-SAME: i64 [[A:%.*]], i1 [[B:%.*]]) {
-; CHECK-NEXT: [[C:%.*]] = sext i1 [[B]] to i64
-; CHECK-NEXT: [[D:%.*]] = xor i64 [[C]], [[A]]
-; CHECK-NEXT: [[R:%.*]] = sub i64 [[D]], [[C]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[A]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i64 [[TMP1]], i64 [[A]]
; CHECK-NEXT: ret i64 [[R]]
;
%c = sext i1 %b to i64
@@ -18,9 +17,8 @@ define i64 @foo(i64 %a, i1 %b) {
define i64 @bar(i64 %a, i1 %b) {
; CHECK-LABEL: define i64 @bar(
; CHECK-SAME: i64 [[A:%.*]], i1 [[B:%.*]]) {
-; CHECK-NEXT: [[C:%.*]] = sext i1 [[B]] to i64
-; CHECK-NEXT: [[D:%.*]] = xor i64 [[C]], [[A]]
-; CHECK-NEXT: [[R:%.*]] = sub i64 [[C]], [[D]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[A]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i64 [[A]], i64 [[TMP1]]
; CHECK-NEXT: ret i64 [[R]]
;
%c = sext i1 %b to i64
>From d7ee2a347ddab4c12d9c12511a346ce0fe72bb4a Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Fri, 26 Jan 2024 16:06:42 +0800
Subject: [PATCH 10/14] Rename
---
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index b4158e240b89cd..7c8c918a4e021f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2452,14 +2452,14 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
// (sub (xor X, (sext C)), (sext C)) => (select C, (neg X), X)
// (sub (sext C), (xor X, (sext C))) => (select C, X, (neg X))
Value *C0, *X;
- auto m_SubXorSext = [&C0, &X](Value *LHS, Value *RHS) {
+ auto m_SubXorCmp = [&C0, &X](Value *LHS, Value *RHS) {
return match(LHS, m_c_Xor(m_Value(X), m_SExt(m_OneUse(m_Value(C0))))) &&
(C0->getType()->getScalarSizeInBits() == 1) &&
match(RHS, m_SExt(m_Specific(C0)));
};
- if (m_SubXorSext(Op0, Op1))
+ if (m_SubXorCmp(Op0, Op1))
return SelectInst::Create(C0, Builder.CreateNeg(X), X);
- if (m_SubXorSext(Op1, Op0))
+ if (m_SubXorCmp(Op1, Op0))
return SelectInst::Create(C0, X, Builder.CreateNeg(X));
}
>From 386a2f5f4185c567a16b2d2c67fdd9ac8ae1167d Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Fri, 26 Jan 2024 16:08:00 +0800
Subject: [PATCH 11/14] Rename
---
.../Transforms/InstCombine/InstCombineAddSub.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 7c8c918a4e021f..659416145bf264 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2451,16 +2451,16 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
{
// (sub (xor X, (sext C)), (sext C)) => (select C, (neg X), X)
// (sub (sext C), (xor X, (sext C))) => (select C, X, (neg X))
- Value *C0, *X;
- auto m_SubXorCmp = [&C0, &X](Value *LHS, Value *RHS) {
- return match(LHS, m_c_Xor(m_Value(X), m_SExt(m_OneUse(m_Value(C0))))) &&
- (C0->getType()->getScalarSizeInBits() == 1) &&
- match(RHS, m_SExt(m_Specific(C0)));
+ Value *C, *X;
+ auto m_SubXorCmp = [&C, &X](Value *LHS, Value *RHS) {
+ return match(LHS, m_c_Xor(m_Value(X), m_SExt(m_OneUse(m_Value(C))))) &&
+ (C->getType()->getScalarSizeInBits() == 1) &&
+ match(RHS, m_SExt(m_Specific(C)));
};
if (m_SubXorCmp(Op0, Op1))
- return SelectInst::Create(C0, Builder.CreateNeg(X), X);
+ return SelectInst::Create(C, Builder.CreateNeg(X), X);
if (m_SubXorCmp(Op1, Op0))
- return SelectInst::Create(C0, X, Builder.CreateNeg(X));
+ return SelectInst::Create(C, X, Builder.CreateNeg(X));
}
if (Instruction *R = tryFoldInstWithCtpopWithNot(&I))
>From 50a2c1b02708c8c68c8e325acf992b384e91355a Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Sat, 27 Jan 2024 11:11:15 +0800
Subject: [PATCH 12/14] Update
---
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 659416145bf264..f2f41119e02e66 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2453,9 +2453,9 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
// (sub (sext C), (xor X, (sext C))) => (select C, X, (neg X))
Value *C, *X;
auto m_SubXorCmp = [&C, &X](Value *LHS, Value *RHS) {
- return match(LHS, m_c_Xor(m_Value(X), m_SExt(m_OneUse(m_Value(C))))) &&
- (C->getType()->getScalarSizeInBits() == 1) &&
- match(RHS, m_SExt(m_Specific(C)));
+ return match(LHS, m_c_Xor(m_Value(X), m_Specific(RHS))) &&
+ match(RHS, m_SExt(m_Value(C))) &&
+ (C->getType()->getScalarSizeInBits() == 1);
};
if (m_SubXorCmp(Op0, Op1))
return SelectInst::Create(C, Builder.CreateNeg(X), X);
>From 994e6b57210266d78bf2fb13355e225374451db0 Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Mon, 29 Jan 2024 13:27:30 +0800
Subject: [PATCH 13/14] Add nagative cases
---
.../Transforms/InstCombine/sub-xor-cmp.ll | 72 ++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
index 2c1c0b4f7207a4..e082e620e2bf75 100644
--- a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
+++ b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
@@ -27,7 +27,7 @@ define i64 @bar(i64 %a, i1 %b) {
ret i64 %r
}
-define i64 @absdiff(i64 %0, i64 %1) {
+define i64 @absdiff(i64 %0, i64 %1) {
; CHECK-LABEL: define i64 @absdiff(
; CHECK-SAME: i64 [[TMP0:%.*]], i64 [[TMP1:%.*]]) {
; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[TMP0]], [[TMP1]]
@@ -43,3 +43,73 @@ define i64 @absdiff(i64 %0, i64 %1) {
%7 = sub i64 %6, %4
ret i64 %7
}
+
+; Sext non boolean type.
+define i64 @f(i64 %a, i8 %b) {
+; CHECK-LABEL: define i64 @f(
+; CHECK-SAME: i64 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT: [[C:%.*]] = sext i8 [[B]] to i64
+; CHECK-NEXT: [[D:%.*]] = xor i64 [[C]], [[A]]
+; CHECK-NEXT: [[R:%.*]] = sub i64 [[D]], [[C]]
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %c = sext i8 %b to i64
+ %d = xor i64 %a, %c
+ %r = sub i64 %d, %c
+ ret i64 %r
+}
+
+; Different boolean values.
+define i64 @g(i64 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: define i64 @g(
+; CHECK-SAME: i64 [[A:%.*]], i1 [[B:%.*]], i1 [[C:%.*]]) {
+; CHECK-NEXT: [[D:%.*]] = sext i1 [[B]] to i64
+; CHECK-NEXT: [[E_NEG:%.*]] = zext i1 [[C]] to i64
+; CHECK-NEXT: [[R:%.*]] = add nsw i64 [[E_NEG]], [[D]]
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %d = sext i1 %b to i64
+ %e = sext i1 %c to i64
+ %f = xor i64 %a, %d
+ %r = sub i64 %d, %e
+ ret i64 %r
+}
+
+; (sext C) has multiple uses.
+define i64 @foobar(i64 %a, i1 %b, i64 %x) {
+; CHECK-LABEL: define i64 @foobar(
+; CHECK-SAME: i64 [[A:%.*]], i1 [[B:%.*]], i64 [[X:%.*]]) {
+; CHECK-NEXT: [[C:%.*]] = sext i1 [[B]] to i64
+; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[A]]
+; CHECK-NEXT: [[E:%.*]] = select i1 [[B]], i64 [[TMP1]], i64 [[A]]
+; CHECK-NEXT: [[F:%.*]] = mul i64 [[C]], [[X]]
+; CHECK-NEXT: [[R:%.*]] = add i64 [[F]], [[E]]
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %c = sext i1 %b to i64
+ %d = xor i64 %a, %c
+ %e = sub i64 %d, %c
+ %f = mul i64 %x, %c
+ %r = add i64 %f, %e
+ ret i64 %r
+}
+
+; (xor X, (sext C)) has multiple uses.
+define i64 @bogus(i64 %a, i1 %b, i64 %x) {
+; CHECK-LABEL: define i64 @bogus(
+; CHECK-SAME: i64 [[A:%.*]], i1 [[B:%.*]], i64 [[X:%.*]]) {
+; CHECK-NEXT: [[C:%.*]] = sext i1 [[B]] to i64
+; CHECK-NEXT: [[D:%.*]] = xor i64 [[C]], [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[A]]
+; CHECK-NEXT: [[E:%.*]] = select i1 [[B]], i64 [[TMP1]], i64 [[A]]
+; CHECK-NEXT: [[F:%.*]] = mul i64 [[D]], [[X]]
+; CHECK-NEXT: [[R:%.*]] = add i64 [[F]], [[E]]
+; CHECK-NEXT: ret i64 [[R]]
+;
+ %c = sext i1 %b to i64
+ %d = xor i64 %a, %c
+ %e = sub i64 %d, %c
+ %f = mul i64 %x, %d
+ %r = add i64 %f, %e
+ ret i64 %r
+}
>From 8a3e3b35a8f1d60b2c64220fda6e42406ab969f8 Mon Sep 17 00:00:00 2001
From: Kai Luo <gluokai at gmail.com>
Date: Mon, 29 Jan 2024 13:37:24 +0800
Subject: [PATCH 14/14] Check one use of (xor X, (sext C)) to avoid regression
---
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 3 ++-
llvm/test/Transforms/InstCombine/sub-xor-cmp.ll | 3 +--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index f2f41119e02e66..098bc6936d6042 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2453,7 +2453,8 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
// (sub (sext C), (xor X, (sext C))) => (select C, X, (neg X))
Value *C, *X;
auto m_SubXorCmp = [&C, &X](Value *LHS, Value *RHS) {
- return match(LHS, m_c_Xor(m_Value(X), m_Specific(RHS))) &&
+ return LHS->hasOneUse() &&
+ match(LHS, m_c_Xor(m_Value(X), m_Specific(RHS))) &&
match(RHS, m_SExt(m_Value(C))) &&
(C->getType()->getScalarSizeInBits() == 1);
};
diff --git a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
index e082e620e2bf75..2760905a1a01f2 100644
--- a/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
+++ b/llvm/test/Transforms/InstCombine/sub-xor-cmp.ll
@@ -100,8 +100,7 @@ define i64 @bogus(i64 %a, i1 %b, i64 %x) {
; CHECK-SAME: i64 [[A:%.*]], i1 [[B:%.*]], i64 [[X:%.*]]) {
; CHECK-NEXT: [[C:%.*]] = sext i1 [[B]] to i64
; CHECK-NEXT: [[D:%.*]] = xor i64 [[C]], [[A]]
-; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[A]]
-; CHECK-NEXT: [[E:%.*]] = select i1 [[B]], i64 [[TMP1]], i64 [[A]]
+; CHECK-NEXT: [[E:%.*]] = sub i64 [[D]], [[C]]
; CHECK-NEXT: [[F:%.*]] = mul i64 [[D]], [[X]]
; CHECK-NEXT: [[R:%.*]] = add i64 [[F]], [[E]]
; CHECK-NEXT: ret i64 [[R]]
More information about the llvm-commits
mailing list