Skip to content

Commit 1e86787

Browse files
pfusikHoney Goyal
authored andcommitted
[RISCV] Select (and (shl X, 8), 0xff00) -> (packh zero, X) (llvm#170654)
Similar transforms with "pack" and "packw" are not useful: (pack zero, X) == (slli X, XLEN/2) (packw zero, X) == (slliw X, 16)
1 parent 6aeb2f4 commit 1e86787

File tree

4 files changed

+178
-1
lines changed

4 files changed

+178
-1
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1500,8 +1500,16 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
15001500
if (tryUnsignedBitfieldInsertInZero(Node, DL, VT, X, Msb, Lsb))
15011501
return;
15021502

1503-
// (srli (slli c2+c3), c3)
15041503
if (OneUseOrZExtW && !IsCANDI) {
1504+
// (packh x0, X)
1505+
if (Subtarget->hasStdExtZbkb() && C1 == 0xff00 && C2 == 8) {
1506+
SDNode *PACKH = CurDAG->getMachineNode(
1507+
RISCV::PACKH, DL, VT,
1508+
CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT()), X);
1509+
ReplaceNode(Node, PACKH);
1510+
return;
1511+
}
1512+
// (srli (slli c2+c3), c3)
15051513
SDNode *SLLI = CurDAG->getMachineNode(
15061514
RISCV::SLLI, DL, VT, X,
15071515
CurDAG->getTargetConstant(C2 + Leading, DL, VT));

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,9 @@ def : Pat<(and (or (shl GPR:$rs2, (XLenVT 8)),
652652
def : Pat<(binop_allhusers<or> (shl GPR:$rs2, (XLenVT 8)),
653653
zexti8:$rs1),
654654
(PACKH zexti8:$rs1, GPR:$rs2)>;
655+
656+
def : Pat<(shl (and GPR:$rs2, 0xFF), (XLenVT 8)),
657+
(PACKH (XLenVT X0), GPR:$rs2)>;
655658
} // Predicates = [HasStdExtZbkb]
656659

657660
let Predicates = [HasStdExtZbkb, IsRV32] in {

llvm/test/CodeGen/RISCV/rv32zbkb.ll

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,3 +458,88 @@ define i32 @pack_lo_noext_hi_packh_nozeroext(i32 %a, i8 %1, i8 %2) nounwind {
458458
%g = or i32 %f, %a
459459
ret i32 %g
460460
}
461+
462+
define i32 @packh_zero_i32(i32 %a) nounwind {
463+
; RV32I-LABEL: packh_zero_i32:
464+
; RV32I: # %bb.0:
465+
; RV32I-NEXT: slli a0, a0, 24
466+
; RV32I-NEXT: srli a0, a0, 16
467+
; RV32I-NEXT: ret
468+
;
469+
; RV32ZBKB-LABEL: packh_zero_i32:
470+
; RV32ZBKB: # %bb.0:
471+
; RV32ZBKB-NEXT: packh a0, zero, a0
472+
; RV32ZBKB-NEXT: ret
473+
%shl = shl i32 %a, 8
474+
%and = and i32 %shl, 65280
475+
ret i32 %and
476+
}
477+
478+
define i32 @packh_zero_i32_2(i32 %a) nounwind {
479+
; RV32I-LABEL: packh_zero_i32_2:
480+
; RV32I: # %bb.0:
481+
; RV32I-NEXT: zext.b a0, a0
482+
; RV32I-NEXT: slli a0, a0, 8
483+
; RV32I-NEXT: ret
484+
;
485+
; RV32ZBKB-LABEL: packh_zero_i32_2:
486+
; RV32ZBKB: # %bb.0:
487+
; RV32ZBKB-NEXT: packh a0, zero, a0
488+
; RV32ZBKB-NEXT: ret
489+
%and = and i32 %a, 255
490+
%shl = shl i32 %and, 8
491+
ret i32 %shl
492+
}
493+
494+
define i64 @packh_zero_i64(i64 %a) nounwind {
495+
; RV32I-LABEL: packh_zero_i64:
496+
; RV32I: # %bb.0:
497+
; RV32I-NEXT: slli a0, a0, 24
498+
; RV32I-NEXT: srli a0, a0, 16
499+
; RV32I-NEXT: li a1, 0
500+
; RV32I-NEXT: ret
501+
;
502+
; RV32ZBKB-LABEL: packh_zero_i64:
503+
; RV32ZBKB: # %bb.0:
504+
; RV32ZBKB-NEXT: packh a0, zero, a0
505+
; RV32ZBKB-NEXT: li a1, 0
506+
; RV32ZBKB-NEXT: ret
507+
%shl = shl i64 %a, 8
508+
%and = and i64 %shl, 65280
509+
ret i64 %and
510+
}
511+
512+
define i64 @packh_zero_i64_2(i64 %a) nounwind {
513+
; RV32I-LABEL: packh_zero_i64_2:
514+
; RV32I: # %bb.0:
515+
; RV32I-NEXT: zext.b a0, a0
516+
; RV32I-NEXT: slli a0, a0, 8
517+
; RV32I-NEXT: li a1, 0
518+
; RV32I-NEXT: ret
519+
;
520+
; RV32ZBKB-LABEL: packh_zero_i64_2:
521+
; RV32ZBKB: # %bb.0:
522+
; RV32ZBKB-NEXT: packh a0, zero, a0
523+
; RV32ZBKB-NEXT: li a1, 0
524+
; RV32ZBKB-NEXT: ret
525+
%and = and i64 %a, 255
526+
%shl = shl i64 %and, 8
527+
ret i64 %shl
528+
}
529+
530+
define i32 @packh_zero_i8(i8 %a) nounwind {
531+
; RV32I-LABEL: packh_zero_i8:
532+
; RV32I: # %bb.0:
533+
; RV32I-NEXT: zext.b a0, a0
534+
; RV32I-NEXT: slli a0, a0, 8
535+
; RV32I-NEXT: ret
536+
;
537+
; RV32ZBKB-LABEL: packh_zero_i8:
538+
; RV32ZBKB: # %bb.0:
539+
; RV32ZBKB-NEXT: packh a0, zero, a0
540+
; RV32ZBKB-NEXT: ret
541+
%zext = zext i8 %a to i32
542+
%shl = shl i32 %zext, 8
543+
%and = and i32 %shl, 65280
544+
ret i32 %and
545+
}

llvm/test/CodeGen/RISCV/rv64zbkb.ll

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,84 @@ define i64 @pack_i64_lo_noext_hi_packh_nozeroext(i64 %a, i8 %1, i8 %2, ptr %p) n
636636
%g = or i64 %f, %a
637637
ret i64 %g
638638
}
639+
640+
define i32 @packh_zero_i32(i32 %a) nounwind {
641+
; RV64I-LABEL: packh_zero_i32:
642+
; RV64I: # %bb.0:
643+
; RV64I-NEXT: slli a0, a0, 56
644+
; RV64I-NEXT: srli a0, a0, 48
645+
; RV64I-NEXT: ret
646+
;
647+
; RV64ZBKB-LABEL: packh_zero_i32:
648+
; RV64ZBKB: # %bb.0:
649+
; RV64ZBKB-NEXT: packh a0, zero, a0
650+
; RV64ZBKB-NEXT: ret
651+
%shl = shl i32 %a, 8
652+
%and = and i32 %shl, 65280
653+
ret i32 %and
654+
}
655+
656+
define i32 @packh_zero_i32_2(i32 %a) nounwind {
657+
; RV64I-LABEL: packh_zero_i32_2:
658+
; RV64I: # %bb.0:
659+
; RV64I-NEXT: zext.b a0, a0
660+
; RV64I-NEXT: slli a0, a0, 8
661+
; RV64I-NEXT: ret
662+
;
663+
; RV64ZBKB-LABEL: packh_zero_i32_2:
664+
; RV64ZBKB: # %bb.0:
665+
; RV64ZBKB-NEXT: packh a0, zero, a0
666+
; RV64ZBKB-NEXT: ret
667+
%and = and i32 %a, 255
668+
%shl = shl i32 %and, 8
669+
ret i32 %shl
670+
}
671+
672+
define i64 @packh_zero_i64(i64 %a) nounwind {
673+
; RV64I-LABEL: packh_zero_i64:
674+
; RV64I: # %bb.0:
675+
; RV64I-NEXT: slli a0, a0, 56
676+
; RV64I-NEXT: srli a0, a0, 48
677+
; RV64I-NEXT: ret
678+
;
679+
; RV64ZBKB-LABEL: packh_zero_i64:
680+
; RV64ZBKB: # %bb.0:
681+
; RV64ZBKB-NEXT: packh a0, zero, a0
682+
; RV64ZBKB-NEXT: ret
683+
%shl = shl i64 %a, 8
684+
%and = and i64 %shl, 65280
685+
ret i64 %and
686+
}
687+
688+
define i64 @packh_zero_i64_2(i64 %a) nounwind {
689+
; RV64I-LABEL: packh_zero_i64_2:
690+
; RV64I: # %bb.0:
691+
; RV64I-NEXT: zext.b a0, a0
692+
; RV64I-NEXT: slli a0, a0, 8
693+
; RV64I-NEXT: ret
694+
;
695+
; RV64ZBKB-LABEL: packh_zero_i64_2:
696+
; RV64ZBKB: # %bb.0:
697+
; RV64ZBKB-NEXT: packh a0, zero, a0
698+
; RV64ZBKB-NEXT: ret
699+
%and = and i64 %a, 255
700+
%shl = shl i64 %and, 8
701+
ret i64 %shl
702+
}
703+
704+
define i32 @packh_zero_i8(i8 %a) nounwind {
705+
; RV64I-LABEL: packh_zero_i8:
706+
; RV64I: # %bb.0:
707+
; RV64I-NEXT: zext.b a0, a0
708+
; RV64I-NEXT: slli a0, a0, 8
709+
; RV64I-NEXT: ret
710+
;
711+
; RV64ZBKB-LABEL: packh_zero_i8:
712+
; RV64ZBKB: # %bb.0:
713+
; RV64ZBKB-NEXT: packh a0, zero, a0
714+
; RV64ZBKB-NEXT: ret
715+
%zext = zext i8 %a to i32
716+
%shl = shl i32 %zext, 8
717+
%and = and i32 %shl, 65280
718+
ret i32 %and
719+
}

0 commit comments

Comments
 (0)