Skip to content

Commit 385e9a2

Browse files
laytonioQingShan Zhang
authored andcommitted
[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
1 parent 2808f59 commit 385e9a2

File tree

4 files changed

+75
-61
lines changed

4 files changed

+75
-61
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,16 +2150,7 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
21502150
!isConstantFPBuildVectorOrConstantFP(CBO))
21512151
return SDValue();
21522152

2153-
EVT VT = Sel.getValueType();
2154-
2155-
// In case of shift value and shift amount may have different VT. For instance
2156-
// on x86 shift amount is i8 regardles of LHS type. Bail out if we have
2157-
// swapped operands and value types do not match. NB: x86 is fine if operands
2158-
// are not swapped with shift amount VT being not bigger than shifted value.
2159-
// TODO: that is possible to check for a shift operation, correct VTs and
2160-
// still perform optimization on x86 if needed.
2161-
if (SelOpNo && VT != CBO.getValueType())
2162-
return SDValue();
2153+
EVT VT = BO->getValueType(0);
21632154

21642155
// We have a select-of-constants followed by a binary operator with a
21652156
// constant. Eliminate the binop by pulling the constant math into the select.

llvm/test/CodeGen/AArch64/select_const.ll

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -437,10 +437,9 @@ define i8 @shl_constant_sel_constants(i1 %cond) {
437437
; CHECK-LABEL: shl_constant_sel_constants:
438438
; CHECK: // %bb.0:
439439
; CHECK-NEXT: tst w0, #0x1
440-
; CHECK-NEXT: mov w8, #2
441-
; CHECK-NEXT: cinc x8, x8, eq
442-
; CHECK-NEXT: mov w9, #1
443-
; CHECK-NEXT: lsl w0, w9, w8
440+
; CHECK-NEXT: mov w8, #8
441+
; CHECK-NEXT: mov w9, #4
442+
; CHECK-NEXT: csel w0, w9, w8, ne
444443
; CHECK-NEXT: ret
445444
%sel = select i1 %cond, i8 2, i8 3
446445
%bo = shl i8 1, %sel
@@ -463,10 +462,9 @@ define i8 @lshr_constant_sel_constants(i1 %cond) {
463462
; CHECK-LABEL: lshr_constant_sel_constants:
464463
; CHECK: // %bb.0:
465464
; CHECK-NEXT: tst w0, #0x1
466-
; CHECK-NEXT: mov w8, #2
467-
; CHECK-NEXT: cinc x8, x8, eq
468-
; CHECK-NEXT: mov w9, #64
469-
; CHECK-NEXT: lsr w0, w9, w8
465+
; CHECK-NEXT: mov w8, #8
466+
; CHECK-NEXT: mov w9, #16
467+
; CHECK-NEXT: csel w0, w9, w8, ne
470468
; CHECK-NEXT: ret
471469
%sel = select i1 %cond, i8 2, i8 3
472470
%bo = lshr i8 64, %sel
@@ -488,10 +486,9 @@ define i8 @ashr_constant_sel_constants(i1 %cond) {
488486
; CHECK-LABEL: ashr_constant_sel_constants:
489487
; CHECK: // %bb.0:
490488
; CHECK-NEXT: tst w0, #0x1
491-
; CHECK-NEXT: mov w8, #2
492-
; CHECK-NEXT: cinc x8, x8, eq
493-
; CHECK-NEXT: mov w9, #-128
494-
; CHECK-NEXT: asr w0, w9, w8
489+
; CHECK-NEXT: mov w8, #-16
490+
; CHECK-NEXT: mov w9, #-32
491+
; CHECK-NEXT: csel w0, w9, w8, ne
495492
; CHECK-NEXT: ret
496493
%sel = select i1 %cond, i8 2, i8 3
497494
%bo = ashr i8 128, %sel

llvm/test/CodeGen/PowerPC/select_const.ll

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -610,13 +610,24 @@ define i8 @sel_constants_shl_constant(i1 %cond) {
610610
}
611611

612612
define i8 @shl_constant_sel_constants(i1 %cond) {
613-
; ALL-LABEL: shl_constant_sel_constants:
614-
; ALL: # %bb.0:
615-
; ALL-NEXT: clrlwi 3, 3, 31
616-
; ALL-NEXT: li 4, 1
617-
; ALL-NEXT: subfic 3, 3, 3
618-
; ALL-NEXT: slw 3, 4, 3
619-
; ALL-NEXT: blr
613+
; ISEL-LABEL: shl_constant_sel_constants:
614+
; ISEL: # %bb.0:
615+
; ISEL-NEXT: andi. 3, 3, 1
616+
; ISEL-NEXT: li 4, 4
617+
; ISEL-NEXT: li 3, 8
618+
; ISEL-NEXT: iselgt 3, 4, 3
619+
; ISEL-NEXT: blr
620+
;
621+
; NO_ISEL-LABEL: shl_constant_sel_constants:
622+
; NO_ISEL: # %bb.0:
623+
; NO_ISEL-NEXT: andi. 3, 3, 1
624+
; NO_ISEL-NEXT: li 4, 4
625+
; NO_ISEL-NEXT: li 3, 8
626+
; NO_ISEL-NEXT: bc 12, 1, .LBB37_1
627+
; NO_ISEL-NEXT: blr
628+
; NO_ISEL-NEXT: .LBB37_1:
629+
; NO_ISEL-NEXT: addi 3, 4, 0
630+
; NO_ISEL-NEXT: blr
620631
%sel = select i1 %cond, i8 2, i8 3
621632
%bo = shl i8 1, %sel
622633
ret i8 %bo
@@ -647,13 +658,24 @@ define i8 @sel_constants_lshr_constant(i1 %cond) {
647658
}
648659

649660
define i8 @lshr_constant_sel_constants(i1 %cond) {
650-
; ALL-LABEL: lshr_constant_sel_constants:
651-
; ALL: # %bb.0:
652-
; ALL-NEXT: clrlwi 3, 3, 31
653-
; ALL-NEXT: li 4, 64
654-
; ALL-NEXT: subfic 3, 3, 3
655-
; ALL-NEXT: srw 3, 4, 3
656-
; ALL-NEXT: blr
661+
; ISEL-LABEL: lshr_constant_sel_constants:
662+
; ISEL: # %bb.0:
663+
; ISEL-NEXT: andi. 3, 3, 1
664+
; ISEL-NEXT: li 4, 16
665+
; ISEL-NEXT: li 3, 8
666+
; ISEL-NEXT: iselgt 3, 4, 3
667+
; ISEL-NEXT: blr
668+
;
669+
; NO_ISEL-LABEL: lshr_constant_sel_constants:
670+
; NO_ISEL: # %bb.0:
671+
; NO_ISEL-NEXT: andi. 3, 3, 1
672+
; NO_ISEL-NEXT: li 4, 16
673+
; NO_ISEL-NEXT: li 3, 8
674+
; NO_ISEL-NEXT: bc 12, 1, .LBB39_1
675+
; NO_ISEL-NEXT: blr
676+
; NO_ISEL-NEXT: .LBB39_1:
677+
; NO_ISEL-NEXT: addi 3, 4, 0
678+
; NO_ISEL-NEXT: blr
657679
%sel = select i1 %cond, i8 2, i8 3
658680
%bo = lshr i8 64, %sel
659681
ret i8 %bo
@@ -672,13 +694,24 @@ define i8 @sel_constants_ashr_constant(i1 %cond) {
672694
}
673695

674696
define i8 @ashr_constant_sel_constants(i1 %cond) {
675-
; ALL-LABEL: ashr_constant_sel_constants:
676-
; ALL: # %bb.0:
677-
; ALL-NEXT: clrlwi 3, 3, 31
678-
; ALL-NEXT: li 4, -128
679-
; ALL-NEXT: subfic 3, 3, 3
680-
; ALL-NEXT: sraw 3, 4, 3
681-
; ALL-NEXT: blr
697+
; ISEL-LABEL: ashr_constant_sel_constants:
698+
; ISEL: # %bb.0:
699+
; ISEL-NEXT: andi. 3, 3, 1
700+
; ISEL-NEXT: li 4, -32
701+
; ISEL-NEXT: li 3, -16
702+
; ISEL-NEXT: iselgt 3, 4, 3
703+
; ISEL-NEXT: blr
704+
;
705+
; NO_ISEL-LABEL: ashr_constant_sel_constants:
706+
; NO_ISEL: # %bb.0:
707+
; NO_ISEL-NEXT: andi. 3, 3, 1
708+
; NO_ISEL-NEXT: li 4, -32
709+
; NO_ISEL-NEXT: li 3, -16
710+
; NO_ISEL-NEXT: bc 12, 1, .LBB41_1
711+
; NO_ISEL-NEXT: blr
712+
; NO_ISEL-NEXT: .LBB41_1:
713+
; NO_ISEL-NEXT: addi 3, 4, 0
714+
; NO_ISEL-NEXT: blr
682715
%sel = select i1 %cond, i8 2, i8 3
683716
%bo = ashr i8 128, %sel
684717
ret i8 %bo

llvm/test/CodeGen/X86/dagcombine-select.ll

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,10 @@ define i32 @sel_constants_shl_constant(i1 %cond) {
194194
define i32 @shl_constant_sel_constants(i1 %cond) {
195195
; CHECK-LABEL: shl_constant_sel_constants:
196196
; CHECK: # %bb.0:
197-
; CHECK-NEXT: movl %edi, %ecx
198-
; CHECK-NEXT: andb $1, %cl
199-
; CHECK-NEXT: xorb $3, %cl
200-
; CHECK-NEXT: movl $1, %eax
201-
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
202-
; CHECK-NEXT: shll %cl, %eax
197+
; CHECK-NEXT: notb %dil
198+
; CHECK-NEXT: movzbl %dil, %eax
199+
; CHECK-NEXT: andl $1, %eax
200+
; CHECK-NEXT: leal 4(,%rax,4), %eax
203201
; CHECK-NEXT: retq
204202
%sel = select i1 %cond, i32 2, i32 3
205203
%bo = shl i32 1, %sel
@@ -209,12 +207,9 @@ define i32 @shl_constant_sel_constants(i1 %cond) {
209207
define i32 @lshr_constant_sel_constants(i1 %cond) {
210208
; CHECK-LABEL: lshr_constant_sel_constants:
211209
; CHECK: # %bb.0:
212-
; CHECK-NEXT: movl %edi, %ecx
213-
; CHECK-NEXT: andb $1, %cl
214-
; CHECK-NEXT: xorb $3, %cl
215-
; CHECK-NEXT: movl $64, %eax
216-
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
217-
; CHECK-NEXT: shrl %cl, %eax
210+
; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
211+
; CHECK-NEXT: andl $1, %edi
212+
; CHECK-NEXT: leal 8(,%rdi,8), %eax
218213
; CHECK-NEXT: retq
219214
%sel = select i1 %cond, i32 2, i32 3
220215
%bo = lshr i32 64, %sel
@@ -224,12 +219,10 @@ define i32 @lshr_constant_sel_constants(i1 %cond) {
224219
define i32 @ashr_constant_sel_constants(i1 %cond) {
225220
; CHECK-LABEL: ashr_constant_sel_constants:
226221
; CHECK: # %bb.0:
227-
; CHECK-NEXT: movl %edi, %ecx
228-
; CHECK-NEXT: andb $1, %cl
229-
; CHECK-NEXT: xorb $3, %cl
230-
; CHECK-NEXT: movl $128, %eax
231-
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
232-
; CHECK-NEXT: shrl %cl, %eax
222+
; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
223+
; CHECK-NEXT: andl $1, %edi
224+
; CHECK-NEXT: shll $4, %edi
225+
; CHECK-NEXT: leal 16(%rdi), %eax
233226
; CHECK-NEXT: retq
234227
%sel = select i1 %cond, i32 2, i32 3
235228
%bo = ashr i32 128, %sel

0 commit comments

Comments
 (0)