[PATCH] R600/SI: Combine min3/max3 instructions
Tom Stellard
tom at stellard.net
Thu Nov 13 08:18:04 PST 2014
On Wed, Oct 22, 2014 at 12:38:53AM +0000, Matt Arsenault wrote:
> http://reviews.llvm.org/D5901
>
> Files:
> lib/Target/R600/AMDGPUISelLowering.cpp
> lib/Target/R600/AMDGPUISelLowering.h
> lib/Target/R600/AMDGPUInstrInfo.td
> lib/Target/R600/SIISelLowering.cpp
> lib/Target/R600/SIISelLowering.h
> lib/Target/R600/SIInstructions.td
> test/CodeGen/R600/fmax3.ll
> test/CodeGen/R600/fmin3.ll
> test/CodeGen/R600/max3.ll
> test/CodeGen/R600/min3.ll
> Index: lib/Target/R600/AMDGPUISelLowering.cpp
> ===================================================================
> --- lib/Target/R600/AMDGPUISelLowering.cpp
> +++ lib/Target/R600/AMDGPUISelLowering.cpp
> @@ -2355,6 +2355,12 @@
> NODE_NAME_CASE(FMIN_LEGACY)
> NODE_NAME_CASE(SMIN)
> NODE_NAME_CASE(UMIN)
> + NODE_NAME_CASE(FMAX3)
> + NODE_NAME_CASE(SMAX3)
> + NODE_NAME_CASE(UMAX3)
> + NODE_NAME_CASE(FMIN3)
> + NODE_NAME_CASE(SMIN3)
> + NODE_NAME_CASE(UMIN3)
> NODE_NAME_CASE(URECIP)
> NODE_NAME_CASE(DIV_SCALE)
> NODE_NAME_CASE(DIV_FMAS)
> Index: lib/Target/R600/AMDGPUISelLowering.h
> ===================================================================
> --- lib/Target/R600/AMDGPUISelLowering.h
> +++ lib/Target/R600/AMDGPUISelLowering.h
> @@ -210,6 +210,12 @@
> FMIN_LEGACY,
> SMIN,
> UMIN,
> + FMAX3,
> + SMAX3,
> + UMAX3,
> + FMIN3,
> + SMIN3,
> + UMIN3,
> URECIP,
> DIV_SCALE,
> DIV_FMAS,
> Index: lib/Target/R600/AMDGPUInstrInfo.td
> ===================================================================
> --- lib/Target/R600/AMDGPUInstrInfo.td
> +++ lib/Target/R600/AMDGPUInstrInfo.td
> @@ -84,7 +84,7 @@
> [SDNPAssociative]
> >;
>
> -// out = min(a, b) a snd b are signed ints
> +// out = min(a, b) a and b are signed ints
> def AMDGPUsmin : SDNode<"AMDGPUISD::SMIN", SDTIntBinOp,
> [SDNPCommutative, SDNPAssociative]
> >;
> @@ -94,6 +94,37 @@
> [SDNPCommutative, SDNPAssociative]
> >;
>
> +// FIXME: TableGen doesn't like commutative instructions with more
> +// than 2 operands.
> +// out = max(a, b, c) a, b and c are floats
> +def AMDGPUfmax3 : SDNode<"AMDGPUISD::FMAX3", SDTFPTernaryOp,
> + [/*SDNPCommutative, SDNPAssociative*/]
> +>;
> +
> +// out = max(a, b, c) a, b, and c are signed ints
> +def AMDGPUsmax3 : SDNode<"AMDGPUISD::SMAX3", AMDGPUDTIntTernaryOp,
> + [/*SDNPCommutative, SDNPAssociative*/]
> +>;
> +
> +// out = max(a, b, c) a, b and c are unsigned ints
> +def AMDGPUumax3 : SDNode<"AMDGPUISD::UMAX3", AMDGPUDTIntTernaryOp,
> + [/*SDNPCommutative, SDNPAssociative*/]
> +>;
> +
> +// out = min(a, b, c) a, b and c are floats
> +def AMDGPUfmin3 : SDNode<"AMDGPUISD::FMIN3", SDTFPTernaryOp,
> + [/*SDNPCommutative, SDNPAssociative*/]
> +>;
> +
> +// out = min(a, b, c) a, b and c are signed ints
> +def AMDGPUsmin3 : SDNode<"AMDGPUISD::SMIN3", AMDGPUDTIntTernaryOp,
> + [/*SDNPCommutative, SDNPAssociative*/]
> +>;
> +
> +// out = min(a, b) a and b are unsigned ints
> +def AMDGPUumin3 : SDNode<"AMDGPUISD::UMIN3", AMDGPUDTIntTernaryOp,
> + [/*SDNPCommutative, SDNPAssociative*/]
> +>;
>
> def AMDGPUcvt_f32_ubyte0 : SDNode<"AMDGPUISD::CVT_F32_UBYTE0",
> SDTIntToFPOp, []>;
> @@ -104,7 +135,6 @@
> def AMDGPUcvt_f32_ubyte3 : SDNode<"AMDGPUISD::CVT_F32_UBYTE3",
> SDTIntToFPOp, []>;
>
> -
Extra whitespace.
> // urecip - This operation is a helper for integer division, it returns the
> // result of 1 / a as a fractional unsigned integer.
> // out = (2^32 / a) + e
> Index: lib/Target/R600/SIISelLowering.cpp
> ===================================================================
> --- lib/Target/R600/SIISelLowering.cpp
> +++ lib/Target/R600/SIISelLowering.cpp
> @@ -1305,6 +1305,7 @@
> return SDValue();
> }
>
> +
Extra whitespace.
LGTM.
> // (shl (add x, c1), c2) -> add (shl x, c2), (shl c1, c2)
>
> // This is a variant of
> @@ -1355,6 +1356,61 @@
> return DAG.getNode(ISD::ADD, SL, VT, ShlX, COffset);
> }
>
> +static unsigned minMaxOpcToMin3Max3Opc(unsigned Opc) {
> + switch (Opc) {
> + case ISD::FMAXNUM:
> + return AMDGPUISD::FMAX3;
> + case AMDGPUISD::SMAX:
> + return AMDGPUISD::SMAX3;
> + case AMDGPUISD::UMAX:
> + return AMDGPUISD::UMAX3;
> + case ISD::FMINNUM:
> + return AMDGPUISD::FMIN3;
> + case AMDGPUISD::SMIN:
> + return AMDGPUISD::SMIN3;
> + case AMDGPUISD::UMIN:
> + return AMDGPUISD::UMIN3;
> + default:
> + llvm_unreachable("Not a min/max opcode");
> + }
> +}
> +
> +SDValue SITargetLowering::performMin3Max3Combine(SDNode *N,
> + DAGCombinerInfo &DCI) const {
> + SelectionDAG &DAG = DCI.DAG;
> +
> + unsigned Opc = N->getOpcode();
> + SDValue Op0 = N->getOperand(0);
> + SDValue Op1 = N->getOperand(1);
> +
> + // Only do this if the inner op has one use since this will just increases
> + // register pressure for no benefit.
> +
> + // max(max(a, b), c)
> + if (Op0.getOpcode() == Opc && Op0.hasOneUse()) {
> + SDLoc DL(N);
> + return DAG.getNode(minMaxOpcToMin3Max3Opc(Opc),
> + DL,
> + N->getValueType(0),
> + Op0.getOperand(0),
> + Op0.getOperand(1),
> + Op1);
> + }
> +
> + // max(a, max(b, c))
> + if (Op1.getOpcode() == Opc && Op1.hasOneUse()) {
> + SDLoc DL(N);
> + return DAG.getNode(minMaxOpcToMin3Max3Opc(Opc),
> + DL,
> + N->getValueType(0),
> + Op0,
> + Op1.getOperand(0),
> + Op1.getOperand(1));
> + }
> +
> + return SDValue();
> +}
> +
> SDValue SITargetLowering::PerformDAGCombine(SDNode *N,
> DAGCombinerInfo &DCI) const {
> SelectionDAG &DAG = DCI.DAG;
> @@ -1382,6 +1438,17 @@
> }
> break;
> }
> + case ISD::FMAXNUM: // TODO: What about fmax_legacy?
> + case ISD::FMINNUM:
> + case AMDGPUISD::SMAX:
> + case AMDGPUISD::SMIN:
> + case AMDGPUISD::UMAX:
> + case AMDGPUISD::UMIN: {
> + if (DCI.getDAGCombineLevel() >= AfterLegalizeDAG &&
> + getTargetMachine().getOptLevel() > CodeGenOpt::None)
> + return performMin3Max3Combine(N, DCI);
> + break;
> + }
>
> case AMDGPUISD::CVT_F32_UBYTE0:
> case AMDGPUISD::CVT_F32_UBYTE1:
> Index: lib/Target/R600/SIISelLowering.h
> ===================================================================
> --- lib/Target/R600/SIISelLowering.h
> +++ lib/Target/R600/SIISelLowering.h
> @@ -59,6 +59,8 @@
> unsigned AS,
> DAGCombinerInfo &DCI) const;
>
> + SDValue performMin3Max3Combine(SDNode *N, DAGCombinerInfo &DCI) const;
> +
> public:
> SITargetLowering(TargetMachine &tm);
>
> Index: lib/Target/R600/SIInstructions.td
> ===================================================================
> --- lib/Target/R600/SIInstructions.td
> +++ lib/Target/R600/SIInstructions.td
> @@ -1544,23 +1544,36 @@
> VOP_F64_F64_F64_F64, fma
> >;
> //def V_LERP_U8 : VOP3_U8 <0x0000014d, "V_LERP_U8", []>;
> +
> defm V_ALIGNBIT_B32 : VOP3Inst <vop3<0x14e>, "V_ALIGNBIT_B32",
> VOP_I32_I32_I32_I32
> >;
> defm V_ALIGNBYTE_B32 : VOP3Inst <vop3<0x14f>, "V_ALIGNBYTE_B32",
> VOP_I32_I32_I32_I32
> >;
> defm V_MULLIT_F32 : VOP3Inst <vop3<0x150>, "V_MULLIT_F32",
> VOP_F32_F32_F32_F32>;
> -////def V_MIN3_F32 : VOP3_MIN3 <0x00000151, "V_MIN3_F32", []>;
> -////def V_MIN3_I32 : VOP3_MIN3 <0x00000152, "V_MIN3_I32", []>;
> -////def V_MIN3_U32 : VOP3_MIN3 <0x00000153, "V_MIN3_U32", []>;
> -////def V_MAX3_F32 : VOP3_MAX3 <0x00000154, "V_MAX3_F32", []>;
> -////def V_MAX3_I32 : VOP3_MAX3 <0x00000155, "V_MAX3_I32", []>;
> -////def V_MAX3_U32 : VOP3_MAX3 <0x00000156, "V_MAX3_U32", []>;
> -////def V_MED3_F32 : VOP3_MED3 <0x00000157, "V_MED3_F32", []>;
> -////def V_MED3_I32 : VOP3_MED3 <0x00000158, "V_MED3_I32", []>;
> -////def V_MED3_U32 : VOP3_MED3 <0x00000159, "V_MED3_U32", []>;
> +defm V_MIN3_F32 : VOP3Inst <vop3<0x151>, "V_MIN3_F32",
> + VOP_F32_F32_F32_F32, AMDGPUfmin3>;
> +
> +defm V_MIN3_I32 : VOP3Inst <vop3<0x152>, "V_MIN3_I32",
> + VOP_I32_I32_I32_I32, AMDGPUsmin3
> +>;
> +defm V_MIN3_U32 : VOP3Inst <vop3<0x153>, "V_MIN3_U32",
> + VOP_I32_I32_I32_I32, AMDGPUumin3
> +>;
> +defm V_MAX3_F32 : VOP3Inst <vop3<0x154>, "V_MAX3_F32",
> + VOP_F32_F32_F32_F32, AMDGPUfmax3
> +>;
> +defm V_MAX3_I32 : VOP3Inst <vop3<0x155>, "V_MAX3_I32",
> + VOP_I32_I32_I32_I32, AMDGPUsmax3
> +>;
> +defm V_MAX3_U32 : VOP3Inst <vop3<0x156>, "V_MAX3_U32",
> + VOP_I32_I32_I32_I32, AMDGPUumax3
> +>;
> +//def V_MED3_F32 : VOP3_MED3 <0x00000157, "V_MED3_F32", []>;
> +//def V_MED3_I32 : VOP3_MED3 <0x00000158, "V_MED3_I32", []>;
> +//def V_MED3_U32 : VOP3_MED3 <0x00000159, "V_MED3_U32", []>;
> //def V_SAD_U8 : VOP3_U8 <0x0000015a, "V_SAD_U8", []>;
> //def V_SAD_HI_U8 : VOP3_U8 <0x0000015b, "V_SAD_HI_U8", []>;
> //def V_SAD_U16 : VOP3_U16 <0x0000015c, "V_SAD_U16", []>;
> Index: test/CodeGen/R600/fmax3.ll
> ===================================================================
> --- /dev/null
> +++ test/CodeGen/R600/fmax3.ll
> @@ -0,0 +1,65 @@
> +; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
> +
> +; SI-LABEL: @test_fmax3_ogt_0:
> +; SI: BUFFER_LOAD_DWORD [[REGA:v[0-9]+]]
> +; SI: BUFFER_LOAD_DWORD [[REGB:v[0-9]+]]
> +; SI: BUFFER_LOAD_DWORD [[REGC:v[0-9]+]]
> +; SI: V_MAX3_F32 [[RESULT:v[0-9]+]], [[REGC]], [[REGB]], [[REGA]]
> +; SI: BUFFER_STORE_DWORD [[RESULT]],
> +; SI: S_ENDPGM
> +define void @test_fmax3_ogt_0(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) nounwind {
> + %a = load float addrspace(1)* %aptr, align 4
> + %b = load float addrspace(1)* %bptr, align 4
> + %c = load float addrspace(1)* %cptr, align 4
> + %fcmp0 = fcmp ogt float %a, %b
> + %f0 = select i1 %fcmp0, float %a, float %b
> + %fcmp1 = fcmp ogt float %f0, %c
> + %f1 = select i1 %fcmp1, float %f0, float %c
> + store float %f1, float addrspace(1)* %out, align 4
> + ret void
> +}
> +
> +; SI-LABEL: @test_fmax3_ogt_1:
> +; SI: V_MAX3_F32
> +; SI: S_ENDPGM
> +define void @test_fmax3_ogt_1(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) nounwind {
> + %a = load float addrspace(1)* %aptr, align 4
> + %b = load float addrspace(1)* %bptr, align 4
> + %c = load float addrspace(1)* %cptr, align 4
> + %fcmp0 = fcmp ogt float %a, %b
> + %f0 = select i1 %fcmp0, float %a, float %b
> + %fcmp1 = fcmp ole float %c, %f0
> + %f1 = select i1 %fcmp1, float %f0, float %c
> + store float %f1, float addrspace(1)* %out, align 4
> + ret void
> +}
> +
> +; SI-LABEL: @test_fmax3_ogt_2:
> +; SI-NOT: V_MAX3_F32
> +; SI: S_ENDPGM
> +define void @test_fmax3_ogt_2(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) nounwind {
> + %a = load float addrspace(1)* %aptr, align 4
> + %b = load float addrspace(1)* %bptr, align 4
> + %c = load float addrspace(1)* %cptr, align 4
> + %fcmp0 = fcmp ogt float %a, %b
> + %f0 = select i1 %fcmp0, float %a, float %b
> + %fcmp1 = fcmp ogt float %c, %f0
> + %f1 = select i1 %fcmp1, float %f0, float %c
> + store float %f1, float addrspace(1)* %out, align 4
> + ret void
> +}
> +
> +; SI-LABEL: @test_fmax3_oge_0
> +; SI: V_MAX3_F32
> +; SI: S_ENDPGM
> +define void @test_fmax3_oge_0(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) nounwind {
> + %a = load float addrspace(1)* %aptr, align 4
> + %b = load float addrspace(1)* %bptr, align 4
> + %c = load float addrspace(1)* %cptr, align 4
> + %fcmp0 = fcmp oge float %a, %b
> + %f0 = select i1 %fcmp0, float %a, float %b
> + %fcmp1 = fcmp oge float %f0, %c
> + %f1 = select i1 %fcmp1, float %f0, float %c
> + store float %f1, float addrspace(1)* %out, align 4
> + ret void
> +}
> Index: test/CodeGen/R600/fmin3.ll
> ===================================================================
> --- /dev/null
> +++ test/CodeGen/R600/fmin3.ll
> @@ -0,0 +1,65 @@
> +; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
> +
> +; SI-LABEL: @test_fmin3_olt_0:
> +; SI: BUFFER_LOAD_DWORD [[REGA:v[0-9]+]]
> +; SI: BUFFER_LOAD_DWORD [[REGB:v[0-9]+]]
> +; SI: BUFFER_LOAD_DWORD [[REGC:v[0-9]+]]
> +; SI: V_MIN3_F32 [[RESULT:v[0-9]+]], [[REGC]], [[REGB]], [[REGA]]
> +; SI: BUFFER_STORE_DWORD [[RESULT]],
> +; SI: S_ENDPGM
> +define void @test_fmin3_olt_0(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) nounwind {
> + %a = load float addrspace(1)* %aptr, align 4
> + %b = load float addrspace(1)* %bptr, align 4
> + %c = load float addrspace(1)* %cptr, align 4
> + %fcmp0 = fcmp olt float %a, %b
> + %f0 = select i1 %fcmp0, float %a, float %b
> + %fcmp1 = fcmp olt float %f0, %c
> + %f1 = select i1 %fcmp1, float %f0, float %c
> + store float %f1, float addrspace(1)* %out, align 4
> + ret void
> +}
> +
> +; SI-LABEL: @test_fmin3_olt_1:
> +; SI: V_MIN3_F32
> +; SI: S_ENDPGM
> +define void @test_fmin3_olt_1(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) nounwind {
> + %a = load float addrspace(1)* %aptr, align 4
> + %b = load float addrspace(1)* %bptr, align 4
> + %c = load float addrspace(1)* %cptr, align 4
> + %fcmp0 = fcmp olt float %a, %b
> + %f0 = select i1 %fcmp0, float %a, float %b
> + %fcmp1 = fcmp oge float %c, %f0
> + %f1 = select i1 %fcmp1, float %f0, float %c
> + store float %f1, float addrspace(1)* %out, align 4
> + ret void
> +}
> +
> +; SI-LABEL: @test_fmin3_olt_2:
> +; SI-NOT: V_MIN3_F32
> +; SI: S_ENDPGM
> +define void @test_fmin3_olt_2(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) nounwind {
> + %a = load float addrspace(1)* %aptr, align 4
> + %b = load float addrspace(1)* %bptr, align 4
> + %c = load float addrspace(1)* %cptr, align 4
> + %fcmp0 = fcmp ole float %a, %b
> + %f0 = select i1 %fcmp0, float %a, float %b
> + %fcmp1 = fcmp olt float %c, %f0
> + %f1 = select i1 %fcmp1, float %f0, float %c
> + store float %f1, float addrspace(1)* %out, align 4
> + ret void
> +}
> +
> +; SI-LABEL: @test_fmin3_olt_3:
> +; SI-NOT: V_MIN3_F32
> +; SI: S_ENDPGM
> +define void @test_fmin3_olt_3(float addrspace(1)* %out, float addrspace(1)* %aptr, float addrspace(1)* %bptr, float addrspace(1)* %cptr) nounwind {
> + %a = load float addrspace(1)* %aptr, align 4
> + %b = load float addrspace(1)* %bptr, align 4
> + %c = load float addrspace(1)* %cptr, align 4
> + %fcmp0 = fcmp olt float %a, %b
> + %f0 = select i1 %fcmp0, float %a, float %b
> + %fcmp1 = fcmp olt float %c, %f0
> + %f1 = select i1 %fcmp1, float %f0, float %c
> + store float %f1, float addrspace(1)* %out, align 4
> + ret void
> +}
> Index: test/CodeGen/R600/max3.ll
> ===================================================================
> --- /dev/null
> +++ test/CodeGen/R600/max3.ll
> @@ -0,0 +1,41 @@
> +; RUN: llc -march=r600 -mcpu=SI < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
> +
> +declare i32 @llvm.r600.read.tidig.x() nounwind readnone
> +
> +; FUNC-LABEL: @v_test_imax3_sgt_i32
> +; SI: V_MAX3_I32
> +define void @v_test_imax3_sgt_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr, i32 addrspace(1)* %cptr) nounwind {
> + %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
> + %gep0 = getelementptr i32 addrspace(1)* %aptr, i32 %tid
> + %gep1 = getelementptr i32 addrspace(1)* %bptr, i32 %tid
> + %gep2 = getelementptr i32 addrspace(1)* %cptr, i32 %tid
> + %outgep = getelementptr i32 addrspace(1)* %out, i32 %tid
> + %a = load i32 addrspace(1)* %gep0, align 4
> + %b = load i32 addrspace(1)* %gep1, align 4
> + %c = load i32 addrspace(1)* %gep2, align 4
> + %icmp0 = icmp sgt i32 %a, %b
> + %i0 = select i1 %icmp0, i32 %a, i32 %b
> + %icmp1 = icmp sgt i32 %i0, %c
> + %i1 = select i1 %icmp1, i32 %i0, i32 %c
> + store i32 %i1, i32 addrspace(1)* %out, align 4
> + ret void
> +}
> +
> +; FUNC-LABEL: @v_test_umax3_ugt_i32
> +; SI: V_MAX3_U32
> +define void @v_test_umax3_ugt_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr, i32 addrspace(1)* %cptr) nounwind {
> + %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
> + %gep0 = getelementptr i32 addrspace(1)* %aptr, i32 %tid
> + %gep1 = getelementptr i32 addrspace(1)* %bptr, i32 %tid
> + %gep2 = getelementptr i32 addrspace(1)* %cptr, i32 %tid
> + %outgep = getelementptr i32 addrspace(1)* %out, i32 %tid
> + %a = load i32 addrspace(1)* %gep0, align 4
> + %b = load i32 addrspace(1)* %gep1, align 4
> + %c = load i32 addrspace(1)* %gep2, align 4
> + %icmp0 = icmp ugt i32 %a, %b
> + %i0 = select i1 %icmp0, i32 %a, i32 %b
> + %icmp1 = icmp ugt i32 %i0, %c
> + %i1 = select i1 %icmp1, i32 %i0, i32 %c
> + store i32 %i1, i32 addrspace(1)* %out, align 4
> + ret void
> +}
> Index: test/CodeGen/R600/min3.ll
> ===================================================================
> --- /dev/null
> +++ test/CodeGen/R600/min3.ll
> @@ -0,0 +1,111 @@
> +; RUN: llc -march=r600 -mcpu=SI < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
> +
> +declare i32 @llvm.r600.read.tidig.x() nounwind readnone
> +
> +; FUNC-LABEL: @v_test_imin3_slt_i32
> +; SI: V_MIN3_I32
> +define void @v_test_imin3_slt_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr, i32 addrspace(1)* %cptr) nounwind {
> + %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
> + %gep0 = getelementptr i32 addrspace(1)* %aptr, i32 %tid
> + %gep1 = getelementptr i32 addrspace(1)* %bptr, i32 %tid
> + %gep2 = getelementptr i32 addrspace(1)* %cptr, i32 %tid
> + %outgep = getelementptr i32 addrspace(1)* %out, i32 %tid
> + %a = load i32 addrspace(1)* %gep0, align 4
> + %b = load i32 addrspace(1)* %gep1, align 4
> + %c = load i32 addrspace(1)* %gep2, align 4
> + %icmp0 = icmp slt i32 %a, %b
> + %i0 = select i1 %icmp0, i32 %a, i32 %b
> + %icmp1 = icmp slt i32 %i0, %c
> + %i1 = select i1 %icmp1, i32 %i0, i32 %c
> + store i32 %i1, i32 addrspace(1)* %outgep, align 4
> + ret void
> +}
> +
> +; FUNC-LABEL: @v_test_umin3_ult_i32
> +; SI: V_MIN3_U32
> +define void @v_test_umin3_ult_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr, i32 addrspace(1)* %cptr) nounwind {
> + %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
> + %gep0 = getelementptr i32 addrspace(1)* %aptr, i32 %tid
> + %gep1 = getelementptr i32 addrspace(1)* %bptr, i32 %tid
> + %gep2 = getelementptr i32 addrspace(1)* %cptr, i32 %tid
> + %outgep = getelementptr i32 addrspace(1)* %out, i32 %tid
> + %a = load i32 addrspace(1)* %gep0, align 4
> + %b = load i32 addrspace(1)* %gep1, align 4
> + %c = load i32 addrspace(1)* %gep2, align 4
> + %icmp0 = icmp ult i32 %a, %b
> + %i0 = select i1 %icmp0, i32 %a, i32 %b
> + %icmp1 = icmp ult i32 %i0, %c
> + %i1 = select i1 %icmp1, i32 %i0, i32 %c
> + store i32 %i1, i32 addrspace(1)* %outgep, align 4
> + ret void
> +}
> +
> +; FUNC-LABEL: @v_test_umin_umin_umin
> +; SI: V_MIN_I32
> +; SI: V_MIN3_I32
> +define void @v_test_umin_umin_umin(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr, i32 addrspace(1)* %cptr) nounwind {
> + %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
> + %tid2 = mul i32 %tid, 2
> + %gep0 = getelementptr i32 addrspace(1)* %aptr, i32 %tid
> + %gep1 = getelementptr i32 addrspace(1)* %bptr, i32 %tid
> + %gep2 = getelementptr i32 addrspace(1)* %cptr, i32 %tid
> +
> + %gep3 = getelementptr i32 addrspace(1)* %aptr, i32 %tid2
> + %gep4 = getelementptr i32 addrspace(1)* %bptr, i32 %tid2
> + %gep5 = getelementptr i32 addrspace(1)* %cptr, i32 %tid2
> +
> + %outgep0 = getelementptr i32 addrspace(1)* %out, i32 %tid
> + %outgep1 = getelementptr i32 addrspace(1)* %out, i32 %tid2
> +
> + %a = load i32 addrspace(1)* %gep0, align 4
> + %b = load i32 addrspace(1)* %gep1, align 4
> + %c = load i32 addrspace(1)* %gep2, align 4
> + %d = load i32 addrspace(1)* %gep3, align 4
> +
> + %icmp0 = icmp slt i32 %a, %b
> + %i0 = select i1 %icmp0, i32 %a, i32 %b
> +
> + %icmp1 = icmp slt i32 %c, %d
> + %i1 = select i1 %icmp1, i32 %c, i32 %d
> +
> + %icmp2 = icmp slt i32 %i0, %i1
> + %i2 = select i1 %icmp2, i32 %i0, i32 %i1
> +
> + store i32 %i2, i32 addrspace(1)* %outgep1, align 4
> + ret void
> +}
> +
> +; FUNC-LABEL: @v_test_umin3_2_uses
> +; SI-NOT: V_MIN3
> +define void @v_test_umin3_2_uses(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr, i32 addrspace(1)* %cptr) nounwind {
> + %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
> + %tid2 = mul i32 %tid, 2
> + %gep0 = getelementptr i32 addrspace(1)* %aptr, i32 %tid
> + %gep1 = getelementptr i32 addrspace(1)* %bptr, i32 %tid
> + %gep2 = getelementptr i32 addrspace(1)* %cptr, i32 %tid
> +
> + %gep3 = getelementptr i32 addrspace(1)* %aptr, i32 %tid2
> + %gep4 = getelementptr i32 addrspace(1)* %bptr, i32 %tid2
> + %gep5 = getelementptr i32 addrspace(1)* %cptr, i32 %tid2
> +
> + %outgep0 = getelementptr i32 addrspace(1)* %out, i32 %tid
> + %outgep1 = getelementptr i32 addrspace(1)* %out, i32 %tid2
> +
> + %a = load i32 addrspace(1)* %gep0, align 4
> + %b = load i32 addrspace(1)* %gep1, align 4
> + %c = load i32 addrspace(1)* %gep2, align 4
> + %d = load i32 addrspace(1)* %gep3, align 4
> +
> + %icmp0 = icmp slt i32 %a, %b
> + %i0 = select i1 %icmp0, i32 %a, i32 %b
> +
> + %icmp1 = icmp slt i32 %c, %d
> + %i1 = select i1 %icmp1, i32 %c, i32 %d
> +
> + %icmp2 = icmp slt i32 %i0, %c
> + %i2 = select i1 %icmp2, i32 %i0, i32 %c
> +
> + store i32 %i2, i32 addrspace(1)* %outgep0, align 4
> + store i32 %i0, i32 addrspace(1)* %outgep1, align 4
> + 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