[PATCH] R600/SI: Handle i64 sext / zest with patterns
Tom Stellard
tom at stellard.net
Tue Jun 10 10:36:15 PDT 2014
On Fri, Jun 06, 2014 at 08:04:38AM +0000, Matt Arsenault wrote:
> http://reviews.llvm.org/D4041
>
> Files:
> lib/Target/R600/SIISelLowering.cpp
> lib/Target/R600/SIISelLowering.h
> lib/Target/R600/SIInstructions.td
> test/CodeGen/R600/sign_extend.ll
LGTM.
> Index: lib/Target/R600/SIISelLowering.cpp
> ===================================================================
> --- lib/Target/R600/SIISelLowering.cpp
> +++ lib/Target/R600/SIISelLowering.cpp
> @@ -115,10 +115,6 @@
> setOperationAction(ISD::SETCC, MVT::v2i1, Expand);
> setOperationAction(ISD::SETCC, MVT::v4i1, Expand);
>
> - setOperationAction(ISD::ANY_EXTEND, MVT::i64, Custom);
> - setOperationAction(ISD::SIGN_EXTEND, MVT::i64, Custom);
> - setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
> -
> setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Legal);
> setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v2i1, Custom);
> setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::v4i1, Custom);
> @@ -656,10 +652,7 @@
>
> case ISD::SELECT: return LowerSELECT(Op, DAG);
> case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
> - case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
> case ISD::STORE: return LowerSTORE(Op, DAG);
> - case ISD::ANY_EXTEND: // Fall-through
> - case ISD::ZERO_EXTEND: return LowerZERO_EXTEND(Op, DAG);
> case ISD::GlobalAddress: return LowerGlobalAddress(MFI, Op, DAG);
> case ISD::INTRINSIC_WO_CHAIN: {
> unsigned IntrinsicID =
> @@ -960,21 +953,6 @@
> return DAG.getNode(ISD::SELECT, DL, VT, Cond, True, False);
> }
>
> -SDValue SITargetLowering::LowerSIGN_EXTEND(SDValue Op,
> - SelectionDAG &DAG) const {
> - EVT VT = Op.getValueType();
> - SDLoc DL(Op);
> -
> - if (VT != MVT::i64) {
> - return SDValue();
> - }
> -
> - SDValue Hi = DAG.getNode(ISD::SRA, DL, MVT::i32, Op.getOperand(0),
> - DAG.getConstant(31, MVT::i32));
> -
> - return DAG.getNode(ISD::BUILD_PAIR, DL, VT, Op.getOperand(0), Hi);
> -}
> -
> SDValue SITargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
> SDLoc DL(Op);
> StoreSDNode *Store = cast<StoreSDNode>(Op);
> @@ -1055,24 +1033,6 @@
> return Chain;
> }
>
> -
> -SDValue SITargetLowering::LowerZERO_EXTEND(SDValue Op,
> - SelectionDAG &DAG) const {
> - EVT VT = Op.getValueType();
> - SDLoc DL(Op);
> -
> - if (VT != MVT::i64) {
> - return SDValue();
> - }
> -
> - SDValue Src = Op.getOperand(0);
> - if (Src.getValueType() != MVT::i32)
> - Src = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i32, Src);
> -
> - SDValue Zero = DAG.getConstant(0, MVT::i32);
> - return DAG.getNode(ISD::BUILD_PAIR, DL, VT, Src, Zero);
> -}
> -
> //===----------------------------------------------------------------------===//
> // Custom DAG optimizations
> //===----------------------------------------------------------------------===//
> Index: lib/Target/R600/SIISelLowering.h
> ===================================================================
> --- lib/Target/R600/SIISelLowering.h
> +++ lib/Target/R600/SIISelLowering.h
> @@ -28,9 +28,7 @@
> SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
> - SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
> - SDValue LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
>
> bool foldImm(SDValue &Operand, int32_t &Immediate,
> Index: lib/Target/R600/SIInstructions.td
> ===================================================================
> --- lib/Target/R600/SIInstructions.td
> +++ lib/Target/R600/SIInstructions.td
> @@ -2459,6 +2459,42 @@
> (S_MOV_B32 -1), sub1)
> >;
>
> +class ZExt_i64_i32_Pat <SDNode ext> : Pat <
> + (i64 (ext i32:$src)),
> + (INSERT_SUBREG (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $src, sub0),
> + (S_MOV_B32 0), sub1)
> +>;
> +
> +class ZExt_i64_i1_Pat <SDNode ext> : Pat <
> + (i64 (ext i1:$src)),
> + (INSERT_SUBREG
> + (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
> + (V_CNDMASK_B32_e64 (i32 0), (i32 1), $src), sub0),
> + (S_MOV_B32 0), sub1)
> +>;
> +
> +
> +def : ZExt_i64_i32_Pat<zext>;
> +def : ZExt_i64_i32_Pat<anyext>;
> +def : ZExt_i64_i1_Pat<zext>;
> +def : ZExt_i64_i1_Pat<anyext>;
> +
> +def : Pat <
> + (i64 (sext i32:$src)),
> + (INSERT_SUBREG
> + (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $src, sub0),
> + (S_ASHR_I32 $src, 31), sub1)
> +>;
> +
> +def : Pat <
> + (i64 (sext i1:$src)),
> + (INSERT_SUBREG
> + (INSERT_SUBREG
> + (i64 (IMPLICIT_DEF)),
> + (V_CNDMASK_B32_e64 0, -1, $src), sub0),
> + (V_CNDMASK_B32_e64 0, -1, $src), sub1)
> +>;
> +
> def : Pat <
> (f32 (sint_to_fp i1:$src)),
> (V_CNDMASK_B32_e64 (i32 0), CONST.FP32_NEG_ONE, $src)
> Index: test/CodeGen/R600/sign_extend.ll
> ===================================================================
> --- test/CodeGen/R600/sign_extend.ll
> +++ test/CodeGen/R600/sign_extend.ll
> @@ -1,12 +1,61 @@
> +; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
>
> -; RUN: llc < %s -march=r600 -mcpu=SI -verify-machineinstrs | FileCheck %s
> +; SI-LABEL: @s_sext_i1_to_i32:
> +; SI: V_CNDMASK_B32_e64
> +; SI: S_ENDPGM
> +define void @s_sext_i1_to_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
> + %cmp = icmp eq i32 %a, %b
> + %sext = sext i1 %cmp to i32
> + store i32 %sext, i32 addrspace(1)* %out, align 4
> + ret void
> +}
>
> -; CHECK: V_ASHR
> -define void @test(i64 addrspace(1)* %out, i32 %a, i32 %b, i32 %c) {
> +; SI-LABEL: @test:
> +; SI: V_ASHR
> +; SI: S_ENDPG
> +define void @test(i64 addrspace(1)* %out, i32 %a, i32 %b, i32 %c) nounwind {
> entry:
> - %0 = mul i32 %a, %b
> - %1 = add i32 %0, %c
> - %2 = sext i32 %1 to i64
> - store i64 %2, i64 addrspace(1)* %out
> + %mul = mul i32 %a, %b
> + %add = add i32 %mul, %c
> + %sext = sext i32 %add to i64
> + store i64 %sext, i64 addrspace(1)* %out, align 8
> + ret void
> +}
> +
> +; SI-LABEL: @s_sext_i1_to_i64:
> +; SI: V_CNDMASK_B32_e64
> +; SI: V_CNDMASK_B32_e64
> +; SI: S_ENDPGM
> +define void @s_sext_i1_to_i64(i64 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
> + %cmp = icmp eq i32 %a, %b
> + %sext = sext i1 %cmp to i64
> + store i64 %sext, i64 addrspace(1)* %out, align 8
> + ret void
> +}
> +
> +; SI-LABEL: @s_sext_i32_to_i64:
> +; SI: S_ASHR_I32
> +; SI: S_ENDPGM
> +define void @s_sext_i32_to_i64(i64 addrspace(1)* %out, i32 %a) nounwind {
> + %sext = sext i32 %a to i64
> + store i64 %sext, i64 addrspace(1)* %out, align 8
> + ret void
> +}
> +
> +; SI-LABEL: @v_sext_i32_to_i64:
> +; SI: V_ASHR
> +; SI: S_ENDPGM
> +define void @v_sext_i32_to_i64(i64 addrspace(1)* %out, i32 addrspace(1)* %in) nounwind {
> + %val = load i32 addrspace(1)* %in, align 4
> + %sext = sext i32 %val to i64
> + store i64 %sext, i64 addrspace(1)* %out, align 8
> + ret void
> +}
> +
> +; SI-LABEL: @s_sext_i16_to_i64:
> +; SI: S_ENDPGM
> +define void @s_sext_i16_to_i64(i64 addrspace(1)* %out, i16 %a) nounwind {
> + %sext = sext i16 %a to i64
> + store i64 %sext, i64 addrspace(1)* %out, align 8
> ret void
> }
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list