Optimize (rs1 & 255) | ((rs2 & 255) << 8) -> (PACKH rs1, rs2).
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D116791
def : Pat<(i64 (or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32)))),
(PACKU GPR:$rs1, GPR:$rs2)>;
}
-let Predicates = [HasStdExtZbp] in
+let Predicates = [HasStdExtZbp] in {
def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),
(and GPR:$rs1, 0x00FF)),
(PACKH GPR:$rs1, GPR:$rs2)>;
+def : Pat<(or (shl (and GPR:$rs2, 0x00FF), (XLenVT 8)),
+ (and GPR:$rs1, 0x00FF)),
+ (PACKH GPR:$rs1, GPR:$rs2)>;
+}
let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXTH_RV32 GPR:$rs)>;
ret i32 %or
}
+define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: packh_i32_2:
+; RV32I: # %bb.0:
+; RV32I-NEXT: andi a0, a0, 255
+; RV32I-NEXT: andi a1, a1, 255
+; RV32I-NEXT: slli a1, a1, 8
+; RV32I-NEXT: or a0, a1, a0
+; RV32I-NEXT: ret
+;
+; RV32ZBP-LABEL: packh_i32_2:
+; RV32ZBP: # %bb.0:
+; RV32ZBP-NEXT: packh a0, a0, a1
+; RV32ZBP-NEXT: ret
+ %and = and i32 %a, 255
+ %and1 = and i32 %b, 255
+ %shl = shl i32 %and1, 8
+ %or = or i32 %shl, %and
+ ret i32 %or
+}
+
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
; RV32I-LABEL: packh_i64:
; RV32I: # %bb.0:
ret i64 %or
}
+define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
+; RV32I-LABEL: packh_i64_2:
+; RV32I: # %bb.0:
+; RV32I-NEXT: andi a0, a0, 255
+; RV32I-NEXT: andi a1, a2, 255
+; RV32I-NEXT: slli a1, a1, 8
+; RV32I-NEXT: or a0, a1, a0
+; RV32I-NEXT: li a1, 0
+; RV32I-NEXT: ret
+;
+; RV32ZBP-LABEL: packh_i64_2:
+; RV32ZBP: # %bb.0:
+; RV32ZBP-NEXT: packh a0, a0, a2
+; RV32ZBP-NEXT: li a1, 0
+; RV32ZBP-NEXT: ret
+ %and = and i64 %a, 255
+ %and1 = and i64 %b, 255
+ %shl = shl i64 %and1, 8
+ %or = or i64 %shl, %and
+ ret i64 %or
+}
+
define i32 @zexth_i32(i32 %a) nounwind {
; RV32I-LABEL: zexth_i32:
; RV32I: # %bb.0:
ret i32 %or
}
+define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
+; RV64I-LABEL: packh_i32_2:
+; RV64I: # %bb.0:
+; RV64I-NEXT: andi a0, a0, 255
+; RV64I-NEXT: andi a1, a1, 255
+; RV64I-NEXT: slli a1, a1, 8
+; RV64I-NEXT: or a0, a1, a0
+; RV64I-NEXT: ret
+;
+; RV64ZBP-LABEL: packh_i32_2:
+; RV64ZBP: # %bb.0:
+; RV64ZBP-NEXT: packh a0, a0, a1
+; RV64ZBP-NEXT: ret
+ %and = and i32 %a, 255
+ %and1 = and i32 %b, 255
+ %shl = shl i32 %and1, 8
+ %or = or i32 %shl, %and
+ ret i32 %or
+}
+
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: packh_i64:
; RV64I: # %bb.0:
ret i64 %or
}
+define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
+; RV64I-LABEL: packh_i64_2:
+; RV64I: # %bb.0:
+; RV64I-NEXT: andi a0, a0, 255
+; RV64I-NEXT: andi a1, a1, 255
+; RV64I-NEXT: slli a1, a1, 8
+; RV64I-NEXT: or a0, a1, a0
+; RV64I-NEXT: ret
+;
+; RV64ZBP-LABEL: packh_i64_2:
+; RV64ZBP: # %bb.0:
+; RV64ZBP-NEXT: packh a0, a0, a1
+; RV64ZBP-NEXT: ret
+ %and = and i64 %a, 255
+ %and1 = and i64 %b, 255
+ %shl = shl i64 %and1, 8
+ %or = or i64 %shl, %and
+ ret i64 %or
+}
+
define i32 @zexth_i32(i32 %a) nounwind {
; RV64I-LABEL: zexth_i32:
; RV64I: # %bb.0: