[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