[llvm] ac522f8 - [DAGCombiner] Fold (sext (not i1 x)) -> (add (zext i1 x), -1)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 6 08:55:05 PST 2020
Author: Layton Kifer
Date: 2020-12-06T11:52:10-05:00
New Revision: ac522f87002ffc20d377e284080c9fa7f63216fc
URL: https://github.com/llvm/llvm-project/commit/ac522f87002ffc20d377e284080c9fa7f63216fc
DIFF: https://github.com/llvm/llvm-project/commit/ac522f87002ffc20d377e284080c9fa7f63216fc.diff
LOG: [DAGCombiner] Fold (sext (not i1 x)) -> (add (zext i1 x), -1)
Move fold of (sext (not i1 x)) -> (add (zext i1 x), -1) from X86 to DAGCombiner to improve codegen on other targets.
Differential Revision: https://reviews.llvm.org/D91589
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/AArch64/select_const.ll
llvm/test/CodeGen/ARM/select_const.ll
llvm/test/CodeGen/PowerPC/select_const.ll
llvm/test/CodeGen/RISCV/sext-zext-trunc.ll
llvm/test/CodeGen/SystemZ/sext-zext.ll
llvm/test/CodeGen/X86/pr44140.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index b1a3d849ed99..c40c2502f536 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -10663,6 +10663,19 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
return DAG.getNode(ISD::ADD, DL, VT, Zext, DAG.getAllOnesConstant(DL, VT));
}
+ // fold sext (not i1 X) -> add (zext i1 X), -1
+ // TODO: This could be extended to handle bool vectors.
+ if (N0.getValueType() == MVT::i1 && isBitwiseNot(N0) && N0.hasOneUse() &&
+ (!LegalOperations || (TLI.isOperationLegal(ISD::ZERO_EXTEND, VT) &&
+ TLI.isOperationLegal(ISD::ADD, VT)))) {
+ // If we can eliminate the 'not', the sext form should be better
+ if (SDValue NewXor = visitXOR(N0.getNode()))
+ return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, NewXor);
+
+ SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0));
+ return DAG.getNode(ISD::ADD, DL, VT, Zext, DAG.getAllOnesConstant(DL, VT));
+ }
+
return SDValue();
}
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index bfd80690347d..690eb39fa0d4 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -46882,7 +46882,6 @@ static SDValue combineSext(SDNode *N, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
SDValue N0 = N->getOperand(0);
EVT VT = N->getValueType(0);
- EVT InVT = N0.getValueType();
SDLoc DL(N);
// (i32 (sext (i8 (x86isd::setcc_carry)))) -> (i32 (x86isd::setcc_carry))
@@ -46911,16 +46910,6 @@ static SDValue combineSext(SDNode *N, SelectionDAG &DAG,
if (SDValue V = combineExtSetcc(N, DAG, Subtarget))
return V;
- if (InVT == MVT::i1 && N0.getOpcode() == ISD::XOR &&
- isAllOnesConstant(N0.getOperand(1)) && N0.hasOneUse()) {
- // Invert and sign-extend a boolean is the same as zero-extend and subtract
- // 1 because 0 becomes -1 and 1 becomes 0. The subtract is efficiently
- // lowered with an LEA or a DEC. This is the same as: select Bool, 0, -1.
- // sext (xor Bool, -1) --> sub (zext Bool), 1
- SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0));
- return DAG.getNode(ISD::SUB, DL, VT, Zext, DAG.getConstant(1, DL, VT));
- }
-
if (SDValue V = combineToExtendBoolVectorInReg(N, DAG, DCI, Subtarget))
return V;
diff --git a/llvm/test/CodeGen/AArch64/select_const.ll b/llvm/test/CodeGen/AArch64/select_const.ll
index affb8150ff85..945e7cdc35ad 100644
--- a/llvm/test/CodeGen/AArch64/select_const.ll
+++ b/llvm/test/CodeGen/AArch64/select_const.ll
@@ -68,8 +68,8 @@ define i32 @select_1_or_0_signext(i1 signext %cond) {
define i32 @select_0_or_neg1(i1 %cond) {
; CHECK-LABEL: select_0_or_neg1:
; CHECK: // %bb.0:
-; CHECK-NEXT: mvn w8, w0
-; CHECK-NEXT: sbfx w0, w8, #0, #1
+; CHECK-NEXT: and w8, w0, #0x1
+; CHECK-NEXT: sub w0, w8, #1 // =1
; CHECK-NEXT: ret
%sel = select i1 %cond, i32 0, i32 -1
ret i32 %sel
@@ -78,8 +78,7 @@ define i32 @select_0_or_neg1(i1 %cond) {
define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
; CHECK-LABEL: select_0_or_neg1_zeroext:
; CHECK: // %bb.0:
-; CHECK-NEXT: mvn w8, w0
-; CHECK-NEXT: sbfx w0, w8, #0, #1
+; CHECK-NEXT: sub w0, w0, #1 // =1
; CHECK-NEXT: ret
%sel = select i1 %cond, i32 0, i32 -1
ret i32 %sel
diff --git a/llvm/test/CodeGen/ARM/select_const.ll b/llvm/test/CodeGen/ARM/select_const.ll
index 500426074736..03f538ea5313 100644
--- a/llvm/test/CodeGen/ARM/select_const.ll
+++ b/llvm/test/CodeGen/ARM/select_const.ll
@@ -137,23 +137,21 @@ define i32 @select_1_or_0_signext(i1 signext %cond) {
define i32 @select_0_or_neg1(i1 %cond) {
; ARM-LABEL: select_0_or_neg1:
; ARM: @ %bb.0:
-; ARM-NEXT: mov r1, #1
-; ARM-NEXT: bic r0, r1, r0
-; ARM-NEXT: rsb r0, r0, #0
+; ARM-NEXT: and r0, r0, #1
+; ARM-NEXT: sub r0, r0, #1
; ARM-NEXT: mov pc, lr
;
; THUMB2-LABEL: select_0_or_neg1:
; THUMB2: @ %bb.0:
-; THUMB2-NEXT: movs r1, #1
-; THUMB2-NEXT: bic.w r0, r1, r0
-; THUMB2-NEXT: rsbs r0, r0, #0
+; THUMB2-NEXT: and r0, r0, #1
+; THUMB2-NEXT: subs r0, #1
; THUMB2-NEXT: bx lr
;
; THUMB-LABEL: select_0_or_neg1:
; THUMB: @ %bb.0:
; THUMB-NEXT: movs r1, #1
-; THUMB-NEXT: bics r1, r0
-; THUMB-NEXT: rsbs r0, r1, #0
+; THUMB-NEXT: ands r1, r0
+; THUMB-NEXT: subs r0, r1, #1
; THUMB-NEXT: bx lr
%sel = select i1 %cond, i32 0, i32 -1
ret i32 %sel
@@ -162,21 +160,17 @@ define i32 @select_0_or_neg1(i1 %cond) {
define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
; ARM-LABEL: select_0_or_neg1_zeroext:
; ARM: @ %bb.0:
-; ARM-NEXT: eor r0, r0, #1
-; ARM-NEXT: rsb r0, r0, #0
+; ARM-NEXT: sub r0, r0, #1
; ARM-NEXT: mov pc, lr
;
; THUMB2-LABEL: select_0_or_neg1_zeroext:
; THUMB2: @ %bb.0:
-; THUMB2-NEXT: eor r0, r0, #1
-; THUMB2-NEXT: rsbs r0, r0, #0
+; THUMB2-NEXT: subs r0, #1
; THUMB2-NEXT: bx lr
;
; THUMB-LABEL: select_0_or_neg1_zeroext:
; THUMB: @ %bb.0:
-; THUMB-NEXT: movs r1, #1
-; THUMB-NEXT: eors r1, r0
-; THUMB-NEXT: rsbs r0, r1, #0
+; THUMB-NEXT: subs r0, r0, #1
; THUMB-NEXT: bx lr
%sel = select i1 %cond, i32 0, i32 -1
ret i32 %sel
diff --git a/llvm/test/CodeGen/PowerPC/select_const.ll b/llvm/test/CodeGen/PowerPC/select_const.ll
index e457ded57f6a..7e8b6297ed3c 100644
--- a/llvm/test/CodeGen/PowerPC/select_const.ll
+++ b/llvm/test/CodeGen/PowerPC/select_const.ll
@@ -69,9 +69,8 @@ define i32 @select_1_or_0_signext(i1 signext %cond) {
define i32 @select_0_or_neg1(i1 %cond) {
; ALL-LABEL: select_0_or_neg1:
; ALL: # %bb.0:
-; ALL-NEXT: not 3, 3
; ALL-NEXT: clrldi 3, 3, 63
-; ALL-NEXT: neg 3, 3
+; ALL-NEXT: addi 3, 3, -1
; ALL-NEXT: blr
%sel = select i1 %cond, i32 0, i32 -1
ret i32 %sel
@@ -80,8 +79,7 @@ define i32 @select_0_or_neg1(i1 %cond) {
define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
; ALL-LABEL: select_0_or_neg1_zeroext:
; ALL: # %bb.0:
-; ALL-NEXT: xori 3, 3, 1
-; ALL-NEXT: neg 3, 3
+; ALL-NEXT: addi 3, 3, -1
; ALL-NEXT: blr
%sel = select i1 %cond, i32 0, i32 -1
ret i32 %sel
diff --git a/llvm/test/CodeGen/RISCV/sext-zext-trunc.ll b/llvm/test/CodeGen/RISCV/sext-zext-trunc.ll
index 2c7a9b13342c..da7faa366e63 100644
--- a/llvm/test/CodeGen/RISCV/sext-zext-trunc.ll
+++ b/llvm/test/CodeGen/RISCV/sext-zext-trunc.ll
@@ -437,20 +437,18 @@ define i32 @trunc_i64_to_i32(i64 %a) nounwind {
ret i32 %1
}
-;; TODO: fold (sext (not x)) -> (add (zext x) -1)
+;; fold (sext (not x)) -> (add (zext x) -1)
define i32 @sext_of_not_i32(i1 %x) {
; RV32I-LABEL: sext_of_not_i32:
; RV32I: # %bb.0:
-; RV32I-NEXT: not a0, a0
; RV32I-NEXT: andi a0, a0, 1
-; RV32I-NEXT: neg a0, a0
+; RV32I-NEXT: addi a0, a0, -1
; RV32I-NEXT: ret
;
; RV64I-LABEL: sext_of_not_i32:
; RV64I: # %bb.0:
-; RV64I-NEXT: not a0, a0
; RV64I-NEXT: andi a0, a0, 1
-; RV64I-NEXT: neg a0, a0
+; RV64I-NEXT: addi a0, a0, -1
; RV64I-NEXT: ret
%xor = xor i1 %x, 1
%sext = sext i1 %xor to i32
@@ -460,24 +458,23 @@ define i32 @sext_of_not_i32(i1 %x) {
define i64 @sext_of_not_i64(i1 %x) {
; RV32I-LABEL: sext_of_not_i64:
; RV32I: # %bb.0:
-; RV32I-NEXT: not a0, a0
-; RV32I-NEXT: andi a0, a0, 1
-; RV32I-NEXT: neg a0, a0
-; RV32I-NEXT: mv a1, a0
+; RV32I-NEXT: andi a1, a0, 1
+; RV32I-NEXT: addi a0, a1, -1
+; RV32I-NEXT: sltu a1, a0, a1
+; RV32I-NEXT: addi a1, a1, -1
; RV32I-NEXT: ret
;
; RV64I-LABEL: sext_of_not_i64:
; RV64I: # %bb.0:
-; RV64I-NEXT: not a0, a0
; RV64I-NEXT: andi a0, a0, 1
-; RV64I-NEXT: neg a0, a0
+; RV64I-NEXT: addi a0, a0, -1
; RV64I-NEXT: ret
%xor = xor i1 %x, 1
%sext = sext i1 %xor to i64
ret i64 %sext
}
-;; TODO: fold (sext (not (setcc a, b, cc))) -> (sext (setcc a, b, !cc))
+;; fold (sext (not (setcc a, b, cc))) -> (sext (setcc a, b, !cc))
define i32 @sext_of_not_cmp_i32(i32 %x) {
; RV32I-LABEL: sext_of_not_cmp_i32:
; RV32I: # %bb.0:
diff --git a/llvm/test/CodeGen/SystemZ/sext-zext.ll b/llvm/test/CodeGen/SystemZ/sext-zext.ll
index 9e2d3bf27742..d48e4ba83588 100644
--- a/llvm/test/CodeGen/SystemZ/sext-zext.ll
+++ b/llvm/test/CodeGen/SystemZ/sext-zext.ll
@@ -1,20 +1,19 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
-;; TODO: fold (sext (not x)) -> (add (zext x) -1)
+;; fold (sext (not x)) -> (add (zext x) -1)
define i32 @sext_of_not(i1 %x) {
; CHECK-LABEL: sext_of_not:
; CHECK: # %bb.0:
-; CHECK-NEXT: xilf %r2, 4294967295
; CHECK-NEXT: nilf %r2, 1
-; CHECK-NEXT: lcr %r2, %r2
+; CHECK-NEXT: ahi %r2, -1
; CHECK-NEXT: br %r14
%xor = xor i1 %x, 1
%sext = sext i1 %xor to i32
ret i32 %sext
}
-;; TODO: fold (sext (not (setcc a, b, cc))) -> (sext (setcc a, b, !cc))
+;; fold (sext (not (setcc a, b, cc))) -> (sext (setcc a, b, !cc))
define i32 @sext_of_not_cmp(i32 %x) {
; CHECK-LABEL: sext_of_not_cmp:
; CHECK: # %bb.0:
diff --git a/llvm/test/CodeGen/X86/pr44140.ll b/llvm/test/CodeGen/X86/pr44140.ll
index 941f45d2d99a..9e623ae5bceb 100644
--- a/llvm/test/CodeGen/X86/pr44140.ll
+++ b/llvm/test/CodeGen/X86/pr44140.ll
@@ -49,8 +49,8 @@ define i32 @main() {
; CHECK-NEXT: movabsq $1010101010101010101, %rcx # imm = 0xE04998456557EB5
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpq %rcx, {{[0-9]+}}(%rsp)
-; CHECK-NEXT: sete %al
-; CHECK-NEXT: decl %eax
+; CHECK-NEXT: setne %al
+; CHECK-NEXT: negl %eax
; CHECK-NEXT: addq $584, %rsp # imm = 0x248
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
More information about the llvm-commits
mailing list