[LoongArch] Lower ANY_EXTEND to ZERO_EXTEND under LASX to avoid scalarization (#201099)
Some integer/floating-point conversion will generate ANY_EXTEND under LASX, lowering it to ZERO_EXTEND to avoid scalarization.
This commit is contained in:
parent
f02b48182b
commit
063ac503e4
4 changed files with 65 additions and 12 deletions
|
|
@ -491,6 +491,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
|
|||
for (MVT VT : {MVT::v4i64, MVT::v8i32, MVT::v16i16}) {
|
||||
setOperationAction(ISD::SIGN_EXTEND, VT, Legal);
|
||||
setOperationAction(ISD::ZERO_EXTEND, VT, Legal);
|
||||
setOperationAction(ISD::ANY_EXTEND, VT, Custom);
|
||||
}
|
||||
for (MVT VT :
|
||||
{MVT::v2i64, MVT::v4i32, MVT::v4i64, MVT::v8i16, MVT::v8i32}) {
|
||||
|
|
@ -678,6 +679,8 @@ SDValue LoongArchTargetLowering::LowerOperation(SDValue Op,
|
|||
return lowerSIGN_EXTEND_VECTOR_INREG(Op, DAG);
|
||||
case ISD::DYNAMIC_STACKALLOC:
|
||||
return lowerDYNAMIC_STACKALLOC(Op, DAG);
|
||||
case ISD::ANY_EXTEND:
|
||||
return lowerANY_EXTEND(Op, DAG);
|
||||
}
|
||||
return SDValue();
|
||||
}
|
||||
|
|
@ -1027,6 +1030,16 @@ SDValue LoongArchTargetLowering::lowerSIGN_EXTEND_VECTOR_INREG(
|
|||
return SDValue();
|
||||
}
|
||||
|
||||
// ANY_EXTEND can be replaced by ZERO_EXTEND when LASX is enabled.
|
||||
SDValue LoongArchTargetLowering::lowerANY_EXTEND(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
assert(Subtarget.hasExtLASX());
|
||||
// We don't have corresponding instrunction for ANY_EXTEND, lowering it to
|
||||
// ZERO_EXTEND won't break its semantics, while avoid scalar extract/insert.
|
||||
return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(Op), Op.getValueType(),
|
||||
Op.getOperand(0));
|
||||
}
|
||||
|
||||
// Lower vecreduce_add using vhaddw instructions.
|
||||
// For Example:
|
||||
// call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)
|
||||
|
|
|
|||
|
|
@ -262,6 +262,7 @@ private:
|
|||
SDValue lowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerSIGN_EXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerANY_EXTEND(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
bool isFPImmLegal(const APFloat &Imm, EVT VT,
|
||||
bool ForCodeSize) const override;
|
||||
|
|
|
|||
48
llvm/test/CodeGen/LoongArch/lasx/vec-shuffle-any-ext.ll
Normal file
48
llvm/test/CodeGen/LoongArch/lasx/vec-shuffle-any-ext.ll
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
||||
; RUN: llc --mtriple=loongarch32 --mattr=+32s,+lasx < %s | FileCheck %s --check-prefixes=CHECK,LA32
|
||||
; RUN: llc --mtriple=loongarch64 --mattr=+lasx < %s | FileCheck %s --check-prefixes=CHECK,LA64
|
||||
|
||||
define void @shuffle_any_ext_8i16_to_8i32(ptr %ptr, ptr %dst) nounwind {
|
||||
; CHECK-LABEL: shuffle_any_ext_8i16_to_8i32:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: vld $vr0, $a0, 0
|
||||
; CHECK-NEXT: vext2xv.wu.hu $xr0, $xr0
|
||||
; CHECK-NEXT: xvst $xr0, $a1, 0
|
||||
; CHECK-NEXT: ret
|
||||
%x = load <8 x i16>, ptr %ptr
|
||||
%y = shufflevector <8 x i16> %x, <8 x i16> poison, <16 x i32> <i32 0, i32 15, i32 1, i32 15, i32 2, i32 13, i32 3, i32 12, i32 4, i32 11, i32 5, i32 10, i32 6, i32 9, i32 7, i32 8>
|
||||
%r = bitcast <16 x i16> %y to <8 x i32>
|
||||
store <8 x i32> %r, ptr %dst
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @shuffle_any_ext_16i8_to_16i16(ptr %ptr, ptr %dst) nounwind {
|
||||
; CHECK-LABEL: shuffle_any_ext_16i8_to_16i16:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: vld $vr0, $a0, 0
|
||||
; CHECK-NEXT: vext2xv.hu.bu $xr0, $xr0
|
||||
; CHECK-NEXT: xvst $xr0, $a1, 0
|
||||
; CHECK-NEXT: ret
|
||||
%x = load <16 x i8>, ptr %ptr
|
||||
%y = shufflevector <16 x i8> %x, <16 x i8> poison, <32 x i32> <i32 0, i32 31, i32 1, i32 31, i32 2, i32 29, i32 3, i32 28, i32 4, i32 27, i32 5, i32 26, i32 6, i32 25, i32 7, i32 24, i32 8, i32 23, i32 9, i32 22, i32 10, i32 21, i32 11, i32 20, i32 12, i32 19, i32 13, i32 18, i32 14, i32 17, i32 15, i32 16>
|
||||
%r = bitcast <32 x i8> %y to <16 x i16>
|
||||
store <16 x i16> %r, ptr %dst
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @shuffle_any_ext_4i32_to_4i64(ptr %ptr, ptr %dst) nounwind {
|
||||
; CHECK-LABEL: shuffle_any_ext_4i32_to_4i64:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: vld $vr0, $a0, 0
|
||||
; CHECK-NEXT: vext2xv.du.wu $xr0, $xr0
|
||||
; CHECK-NEXT: xvst $xr0, $a1, 0
|
||||
; CHECK-NEXT: ret
|
||||
%x = load <4 x i32>, ptr %ptr
|
||||
%y = shufflevector <4 x i32> %x, <4 x i32> poison, <8 x i32> <i32 0, i32 7, i32 1, i32 6, i32 2, i32 5, i32 3, i32 4>
|
||||
%r = bitcast <8 x i32> %y to <4 x i64>
|
||||
store <4 x i64> %r, ptr %dst
|
||||
ret void
|
||||
}
|
||||
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
||||
; LA32: {{.*}}
|
||||
; LA64: {{.*}}
|
||||
|
|
@ -12,10 +12,7 @@ define void @xor_zext_masks_v4i64(ptr %res, ptr %a, ptr %b) nounwind {
|
|||
; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
|
||||
; LA32-NEXT: vldi $vr1, -1777
|
||||
; LA32-NEXT: vxor.v $vr0, $vr0, $vr1
|
||||
; LA32-NEXT: vextrins.w $vr1, $vr0, 2
|
||||
; LA32-NEXT: vextrins.w $vr1, $vr0, 35
|
||||
; LA32-NEXT: vextrins.w $vr0, $vr0, 33
|
||||
; LA32-NEXT: xvpermi.q $xr0, $xr1, 2
|
||||
; LA32-NEXT: vext2xv.du.wu $xr0, $xr0
|
||||
; LA32-NEXT: xvrepli.d $xr1, 1
|
||||
; LA32-NEXT: xvand.v $xr0, $xr0, $xr1
|
||||
; LA32-NEXT: xvst $xr0, $a0, 0
|
||||
|
|
@ -173,10 +170,7 @@ define void @or_zext_masks_v4i64(ptr %res, ptr %a, ptr %b) nounwind {
|
|||
; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
|
||||
; LA32-NEXT: vldi $vr1, -1777
|
||||
; LA32-NEXT: vor.v $vr0, $vr0, $vr1
|
||||
; LA32-NEXT: vextrins.w $vr1, $vr0, 2
|
||||
; LA32-NEXT: vextrins.w $vr1, $vr0, 35
|
||||
; LA32-NEXT: vextrins.w $vr0, $vr0, 33
|
||||
; LA32-NEXT: xvpermi.q $xr0, $xr1, 2
|
||||
; LA32-NEXT: vext2xv.du.wu $xr0, $xr0
|
||||
; LA32-NEXT: xvrepli.d $xr1, 1
|
||||
; LA32-NEXT: xvand.v $xr0, $xr0, $xr1
|
||||
; LA32-NEXT: xvst $xr0, $a0, 0
|
||||
|
|
@ -331,10 +325,7 @@ define void @and_zext_masks_v4i64(ptr %res, ptr %a, ptr %b) nounwind {
|
|||
; LA32-NEXT: xvpermi.d $xr0, $xr0, 216
|
||||
; LA32-NEXT: vldi $vr1, -1777
|
||||
; LA32-NEXT: vand.v $vr0, $vr0, $vr1
|
||||
; LA32-NEXT: vextrins.w $vr1, $vr0, 2
|
||||
; LA32-NEXT: vextrins.w $vr1, $vr0, 35
|
||||
; LA32-NEXT: vextrins.w $vr0, $vr0, 33
|
||||
; LA32-NEXT: xvpermi.q $xr0, $xr1, 2
|
||||
; LA32-NEXT: vext2xv.du.wu $xr0, $xr0
|
||||
; LA32-NEXT: xvrepli.d $xr1, 1
|
||||
; LA32-NEXT: xvand.v $xr0, $xr0, $xr1
|
||||
; LA32-NEXT: xvst $xr0, $a0, 0
|
||||
|
|
|
|||
Loading…
Reference in a new issue