Skip to content

Commit

Permalink
[DAG] Peek through trunc when combining select into shifts.
Browse files Browse the repository at this point in the history
This fixes a regression in D127115

Depends on D127115

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D151916
  • Loading branch information
deadalnix committed Jun 23, 2023
1 parent 65b710e commit 34d8c5b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 36 deletions.
11 changes: 11 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2485,6 +2485,17 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse()) {
SelOpNo = 1;
Sel = BO->getOperand(1);

// Peek through trunc to shift amount type.
if ((BinOpcode == ISD::SHL || BinOpcode == ISD::SRA ||
BinOpcode == ISD::SRL) && Sel.hasOneUse()) {
// This is valid when the truncated bits of x are already zero.
SDValue Op;
KnownBits Known;
if (isTruncateOf(DAG, Sel, Op, Known) &&
Known.countMaxActiveBits() < Sel.getScalarValueSizeInBits())
Sel = Op;
}
}

if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse())
Expand Down
58 changes: 22 additions & 36 deletions llvm/test/CodeGen/X86/dagcombine-select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -209,12 +207,10 @@ define i32 @shl_constant_sel_constants(i1 %cond) {
define i32 @shl_constant_sel_setcc(i32 %a) {
; CHECK-LABEL: shl_constant_sel_setcc:
; 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: xorl %eax, %eax
; CHECK-NEXT: testb $1, %dil
; CHECK-NEXT: sete %al
; CHECK-NEXT: leal 4(,%rax,4), %eax
; CHECK-NEXT: retq
%m = and i32 %a, 1
%cond = icmp ne i32 %m, 0
Expand All @@ -226,12 +222,9 @@ define i32 @shl_constant_sel_setcc(i32 %a) {
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
Expand All @@ -241,12 +234,9 @@ define i32 @lshr_constant_sel_constants(i1 %cond) {
define i32 @lshr_constant_sel_setcc(i32 %a) {
; CHECK-LABEL: lshr_constant_sel_setcc:
; 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
%m = and i32 %a, 1
%cond = icmp ne i32 %m, 0
Expand All @@ -258,12 +248,10 @@ define i32 @lshr_constant_sel_setcc(i32 %a) {
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
Expand All @@ -273,12 +261,10 @@ define i32 @ashr_constant_sel_constants(i1 %cond) {
define i32 @ashr_constant_sel_setcc(i32 %a) {
; CHECK-LABEL: ashr_constant_sel_setcc:
; 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
%m = and i32 %a, 1
%cond = icmp ne i32 %m, 0
Expand Down

0 comments on commit 34d8c5b

Please sign in to comment.