[llvm-branch-commits] [llvm] 385e9a2 - [DAGCombiner] Improve shift by select of constant
QingShan Zhang via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Dec 17 18:28:40 PST 2020
Author: Layton Kifer
Date: 2020-12-18T02:21:42Z
New Revision: 385e9a2a047bc0bee13a21a9016763e694a686a3
URL: https://github.com/llvm/llvm-project/commit/385e9a2a047bc0bee13a21a9016763e694a686a3
DIFF: https://github.com/llvm/llvm-project/commit/385e9a2a047bc0bee13a21a9016763e694a686a3.diff
LOG: [DAGCombiner] Improve shift by select of constant
Clean up a TODO, to support folding a shift of a constant by a
select of constants, on targets with different shift operand sizes.
Reviewed By: RKSimon, lebedev.ri
Differential Revision: https://reviews.llvm.org/D90349
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/AArch64/select_const.ll
llvm/test/CodeGen/PowerPC/select_const.ll
llvm/test/CodeGen/X86/dagcombine-select.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 212e0a2ea988..74d3e1adcd6c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2150,16 +2150,7 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
!isConstantFPBuildVectorOrConstantFP(CBO))
return SDValue();
- EVT VT = Sel.getValueType();
-
- // In case of shift value and shift amount may have
diff erent VT. For instance
- // on x86 shift amount is i8 regardles of LHS type. Bail out if we have
- // swapped operands and value types do not match. NB: x86 is fine if operands
- // are not swapped with shift amount VT being not bigger than shifted value.
- // TODO: that is possible to check for a shift operation, correct VTs and
- // still perform optimization on x86 if needed.
- if (SelOpNo && VT != CBO.getValueType())
- return SDValue();
+ EVT VT = BO->getValueType(0);
// We have a select-of-constants followed by a binary operator with a
// constant. Eliminate the binop by pulling the constant math into the select.
diff --git a/llvm/test/CodeGen/AArch64/select_const.ll b/llvm/test/CodeGen/AArch64/select_const.ll
index 945e7cdc35ad..f58232e2ee89 100644
--- a/llvm/test/CodeGen/AArch64/select_const.ll
+++ b/llvm/test/CodeGen/AArch64/select_const.ll
@@ -437,10 +437,9 @@ define i8 @shl_constant_sel_constants(i1 %cond) {
; CHECK-LABEL: shl_constant_sel_constants:
; CHECK: // %bb.0:
; CHECK-NEXT: tst w0, #0x1
-; CHECK-NEXT: mov w8, #2
-; CHECK-NEXT: cinc x8, x8, eq
-; CHECK-NEXT: mov w9, #1
-; CHECK-NEXT: lsl w0, w9, w8
+; CHECK-NEXT: mov w8, #8
+; CHECK-NEXT: mov w9, #4
+; CHECK-NEXT: csel w0, w9, w8, ne
; CHECK-NEXT: ret
%sel = select i1 %cond, i8 2, i8 3
%bo = shl i8 1, %sel
@@ -463,10 +462,9 @@ define i8 @lshr_constant_sel_constants(i1 %cond) {
; CHECK-LABEL: lshr_constant_sel_constants:
; CHECK: // %bb.0:
; CHECK-NEXT: tst w0, #0x1
-; CHECK-NEXT: mov w8, #2
-; CHECK-NEXT: cinc x8, x8, eq
-; CHECK-NEXT: mov w9, #64
-; CHECK-NEXT: lsr w0, w9, w8
+; CHECK-NEXT: mov w8, #8
+; CHECK-NEXT: mov w9, #16
+; CHECK-NEXT: csel w0, w9, w8, ne
; CHECK-NEXT: ret
%sel = select i1 %cond, i8 2, i8 3
%bo = lshr i8 64, %sel
@@ -488,10 +486,9 @@ define i8 @ashr_constant_sel_constants(i1 %cond) {
; CHECK-LABEL: ashr_constant_sel_constants:
; CHECK: // %bb.0:
; CHECK-NEXT: tst w0, #0x1
-; CHECK-NEXT: mov w8, #2
-; CHECK-NEXT: cinc x8, x8, eq
-; CHECK-NEXT: mov w9, #-128
-; CHECK-NEXT: asr w0, w9, w8
+; CHECK-NEXT: mov w8, #-16
+; CHECK-NEXT: mov w9, #-32
+; CHECK-NEXT: csel w0, w9, w8, ne
; CHECK-NEXT: ret
%sel = select i1 %cond, i8 2, i8 3
%bo = ashr i8 128, %sel
diff --git a/llvm/test/CodeGen/PowerPC/select_const.ll b/llvm/test/CodeGen/PowerPC/select_const.ll
index 7e8b6297ed3c..804cc7736bf8 100644
--- a/llvm/test/CodeGen/PowerPC/select_const.ll
+++ b/llvm/test/CodeGen/PowerPC/select_const.ll
@@ -610,13 +610,24 @@ define i8 @sel_constants_shl_constant(i1 %cond) {
}
define i8 @shl_constant_sel_constants(i1 %cond) {
-; ALL-LABEL: shl_constant_sel_constants:
-; ALL: # %bb.0:
-; ALL-NEXT: clrlwi 3, 3, 31
-; ALL-NEXT: li 4, 1
-; ALL-NEXT: subfic 3, 3, 3
-; ALL-NEXT: slw 3, 4, 3
-; ALL-NEXT: blr
+; ISEL-LABEL: shl_constant_sel_constants:
+; ISEL: # %bb.0:
+; ISEL-NEXT: andi. 3, 3, 1
+; ISEL-NEXT: li 4, 4
+; ISEL-NEXT: li 3, 8
+; ISEL-NEXT: iselgt 3, 4, 3
+; ISEL-NEXT: blr
+;
+; NO_ISEL-LABEL: shl_constant_sel_constants:
+; NO_ISEL: # %bb.0:
+; NO_ISEL-NEXT: andi. 3, 3, 1
+; NO_ISEL-NEXT: li 4, 4
+; NO_ISEL-NEXT: li 3, 8
+; NO_ISEL-NEXT: bc 12, 1, .LBB37_1
+; NO_ISEL-NEXT: blr
+; NO_ISEL-NEXT: .LBB37_1:
+; NO_ISEL-NEXT: addi 3, 4, 0
+; NO_ISEL-NEXT: blr
%sel = select i1 %cond, i8 2, i8 3
%bo = shl i8 1, %sel
ret i8 %bo
@@ -647,13 +658,24 @@ define i8 @sel_constants_lshr_constant(i1 %cond) {
}
define i8 @lshr_constant_sel_constants(i1 %cond) {
-; ALL-LABEL: lshr_constant_sel_constants:
-; ALL: # %bb.0:
-; ALL-NEXT: clrlwi 3, 3, 31
-; ALL-NEXT: li 4, 64
-; ALL-NEXT: subfic 3, 3, 3
-; ALL-NEXT: srw 3, 4, 3
-; ALL-NEXT: blr
+; ISEL-LABEL: lshr_constant_sel_constants:
+; ISEL: # %bb.0:
+; ISEL-NEXT: andi. 3, 3, 1
+; ISEL-NEXT: li 4, 16
+; ISEL-NEXT: li 3, 8
+; ISEL-NEXT: iselgt 3, 4, 3
+; ISEL-NEXT: blr
+;
+; NO_ISEL-LABEL: lshr_constant_sel_constants:
+; NO_ISEL: # %bb.0:
+; NO_ISEL-NEXT: andi. 3, 3, 1
+; NO_ISEL-NEXT: li 4, 16
+; NO_ISEL-NEXT: li 3, 8
+; NO_ISEL-NEXT: bc 12, 1, .LBB39_1
+; NO_ISEL-NEXT: blr
+; NO_ISEL-NEXT: .LBB39_1:
+; NO_ISEL-NEXT: addi 3, 4, 0
+; NO_ISEL-NEXT: blr
%sel = select i1 %cond, i8 2, i8 3
%bo = lshr i8 64, %sel
ret i8 %bo
@@ -672,13 +694,24 @@ define i8 @sel_constants_ashr_constant(i1 %cond) {
}
define i8 @ashr_constant_sel_constants(i1 %cond) {
-; ALL-LABEL: ashr_constant_sel_constants:
-; ALL: # %bb.0:
-; ALL-NEXT: clrlwi 3, 3, 31
-; ALL-NEXT: li 4, -128
-; ALL-NEXT: subfic 3, 3, 3
-; ALL-NEXT: sraw 3, 4, 3
-; ALL-NEXT: blr
+; ISEL-LABEL: ashr_constant_sel_constants:
+; ISEL: # %bb.0:
+; ISEL-NEXT: andi. 3, 3, 1
+; ISEL-NEXT: li 4, -32
+; ISEL-NEXT: li 3, -16
+; ISEL-NEXT: iselgt 3, 4, 3
+; ISEL-NEXT: blr
+;
+; NO_ISEL-LABEL: ashr_constant_sel_constants:
+; NO_ISEL: # %bb.0:
+; NO_ISEL-NEXT: andi. 3, 3, 1
+; NO_ISEL-NEXT: li 4, -32
+; NO_ISEL-NEXT: li 3, -16
+; NO_ISEL-NEXT: bc 12, 1, .LBB41_1
+; NO_ISEL-NEXT: blr
+; NO_ISEL-NEXT: .LBB41_1:
+; NO_ISEL-NEXT: addi 3, 4, 0
+; NO_ISEL-NEXT: blr
%sel = select i1 %cond, i8 2, i8 3
%bo = ashr i8 128, %sel
ret i8 %bo
diff --git a/llvm/test/CodeGen/X86/dagcombine-select.ll b/llvm/test/CodeGen/X86/dagcombine-select.ll
index ff022c3bf0fa..9bebec6f5ecd 100644
--- a/llvm/test/CodeGen/X86/dagcombine-select.ll
+++ b/llvm/test/CodeGen/X86/dagcombine-select.ll
@@ -194,12 +194,10 @@ define i32 @sel_constants_shl_constant(i1 %cond) {
define i32 @shl_constant_sel_constants(i1 %cond) {
; CHECK-LABEL: shl_constant_sel_constants:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %ecx
-; CHECK-NEXT: andb $1, %cl
-; CHECK-NEXT: xorb $3, %cl
-; CHECK-NEXT: movl $1, %eax
-; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT: shll %cl, %eax
+; CHECK-NEXT: notb %dil
+; CHECK-NEXT: movzbl %dil, %eax
+; CHECK-NEXT: andl $1, %eax
+; CHECK-NEXT: leal 4(,%rax,4), %eax
; CHECK-NEXT: retq
%sel = select i1 %cond, i32 2, i32 3
%bo = shl i32 1, %sel
@@ -209,12 +207,9 @@ define i32 @shl_constant_sel_constants(i1 %cond) {
define i32 @lshr_constant_sel_constants(i1 %cond) {
; CHECK-LABEL: lshr_constant_sel_constants:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %ecx
-; CHECK-NEXT: andb $1, %cl
-; CHECK-NEXT: xorb $3, %cl
-; CHECK-NEXT: movl $64, %eax
-; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT: shrl %cl, %eax
+; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
+; CHECK-NEXT: andl $1, %edi
+; CHECK-NEXT: leal 8(,%rdi,8), %eax
; CHECK-NEXT: retq
%sel = select i1 %cond, i32 2, i32 3
%bo = lshr i32 64, %sel
@@ -224,12 +219,10 @@ define i32 @lshr_constant_sel_constants(i1 %cond) {
define i32 @ashr_constant_sel_constants(i1 %cond) {
; CHECK-LABEL: ashr_constant_sel_constants:
; CHECK: # %bb.0:
-; CHECK-NEXT: movl %edi, %ecx
-; CHECK-NEXT: andb $1, %cl
-; CHECK-NEXT: xorb $3, %cl
-; CHECK-NEXT: movl $128, %eax
-; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
-; CHECK-NEXT: shrl %cl, %eax
+; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
+; CHECK-NEXT: andl $1, %edi
+; CHECK-NEXT: shll $4, %edi
+; CHECK-NEXT: leal 16(%rdi), %eax
; CHECK-NEXT: retq
%sel = select i1 %cond, i32 2, i32 3
%bo = ashr i32 128, %sel
More information about the llvm-branch-commits
mailing list