From 1f143aa3e97af35f2d0f089b5ece48f103498a75 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 31 Mar 2014 14:01:55 +0000 Subject: [PATCH] R600/SI: Lower i64 SELECT by bitcasting to a vector type This allows allows us to replace ISD::EXTRACT_ELEMENT, which is lowered using shifts, with ISD::EXTRACT_VECTOR_ELT, which is a no-op. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205187 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/SIISelLowering.cpp | 16 +++++++++------- lib/Target/R600/SIInstructions.td | 1 + test/CodeGen/R600/select64.ll | 3 +++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/Target/R600/SIISelLowering.cpp b/lib/Target/R600/SIISelLowering.cpp index 0e9de5df7a2..d4978cc66c6 100644 --- a/lib/Target/R600/SIISelLowering.cpp +++ b/lib/Target/R600/SIISelLowering.cpp @@ -796,23 +796,25 @@ SDValue SITargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); SDValue Cond = Op.getOperand(0); - SDValue LHS = Op.getOperand(1); - SDValue RHS = Op.getOperand(2); SDValue Zero = DAG.getConstant(0, MVT::i32); SDValue One = DAG.getConstant(1, MVT::i32); - SDValue Lo0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, LHS, Zero); - SDValue Lo1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, RHS, Zero); + SDValue LHS = DAG.getNode(ISD::BITCAST, DL, MVT::v2i32, Op.getOperand(1)); + SDValue RHS = DAG.getNode(ISD::BITCAST, DL, MVT::v2i32, Op.getOperand(2)); + + SDValue Lo0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, LHS, Zero); + SDValue Lo1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, RHS, Zero); SDValue Lo = DAG.getSelect(DL, MVT::i32, Cond, Lo0, Lo1); - SDValue Hi0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, LHS, One); - SDValue Hi1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, RHS, One); + SDValue Hi0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, LHS, One); + SDValue Hi1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, RHS, One); SDValue Hi = DAG.getSelect(DL, MVT::i32, Cond, Hi0, Hi1); - return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi); + SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v2i32, Lo, Hi); + return DAG.getNode(ISD::BITCAST, DL, MVT::i64, Res); } SDValue SITargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td index 8e320929fb7..55d31eaa5bf 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -1686,6 +1686,7 @@ def : BitConvert ; def : BitConvert ; def : BitConvert ; def : BitConvert ; +def : BitConvert ; def : BitConvert ; def : BitConvert ; diff --git a/test/CodeGen/R600/select64.ll b/test/CodeGen/R600/select64.ll index 2b905a3035c..6b87d9865ad 100644 --- a/test/CodeGen/R600/select64.ll +++ b/test/CodeGen/R600/select64.ll @@ -1,6 +1,9 @@ ; RUN: llc < %s -march=r600 -mcpu=SI -verify-machineinstrs | FileCheck %s ; CHECK-LABEL: @select0 +; i64 select should be split into two i32 selects, and we shouldn't need +; to use a shfit to extract the hi dword of the input. +; CHECK-NOT: S_LSHR_B64 ; CHECK: V_CNDMASK ; CHECK: V_CNDMASK define void @select0(i64 addrspace(1)* %out, i32 %cond, i64 %in) { -- 2.11.0