[llvm-branch-commits] [llvm-branch] r165527 - in /llvm/branches/R600: lib/Target/AMDGPU/R600ISelLowering.cpp test/CodeGen/R600/fcmp-cnde-int-args.ll
Tom Stellard
thomas.stellard at amd.com
Tue Oct 9 11:49:05 PDT 2012
Author: tstellar
Date: Tue Oct 9 13:49:05 2012
New Revision: 165527
URL: http://llvm.org/viewvc/llvm-project?rev=165527&view=rev
Log:
R600: Prefer lowering SELECT_CC to CND* instructions over SET* instructions
SET* instructions are more expensive, because in some cases they require
additional instructions to convert their result to the correct type.
Added:
llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll
Modified:
llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp
Modified: llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp?rev=165527&r1=165526&r2=165527&view=diff
==============================================================================
--- llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp (original)
+++ llvm/branches/R600/lib/Target/AMDGPU/R600ISelLowering.cpp Tue Oct 9 13:49:05 2012
@@ -550,6 +550,56 @@
// LHS and RHS are guaranteed to be the same value type
EVT CompareVT = LHS.getValueType();
+ // Check if we can lower this to a native operation.
+
+ // Try to lower to a CND* instruction:
+ // CND* instructions requires RHS to be zero. Some SELECT_CC nodes that
+ // can be lowered to CND* instructions can also be lowered to SET*
+ // instructions. CND* instructions are cheaper, because they dont't
+ // require additional instructions to convert their result to the correct
+ // value type, so this check should be first.
+ if (isZero(LHS) || isZero(RHS)) {
+ SDValue Cond = (isZero(LHS) ? RHS : LHS);
+ SDValue Zero = (isZero(LHS) ? LHS : RHS);
+ ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
+ if (CompareVT != VT) {
+ // Bitcast True / False to the correct types. This will end up being
+ // a nop, but it allows us to define only a single pattern in the
+ // .TD files for each CND* instruction rather than having to have
+ // one pattern for integer True/False and one for fp True/False
+ True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True);
+ False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False);
+ }
+ if (isZero(LHS)) {
+ CCOpcode = ISD::getSetCCSwappedOperands(CCOpcode);
+ }
+
+ switch (CCOpcode) {
+ case ISD::SETONE:
+ case ISD::SETUNE:
+ case ISD::SETNE:
+ case ISD::SETULE:
+ case ISD::SETULT:
+ case ISD::SETOLE:
+ case ISD::SETOLT:
+ case ISD::SETLE:
+ case ISD::SETLT:
+ CCOpcode = ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32);
+ Temp = True;
+ True = False;
+ False = Temp;
+ break;
+ default:
+ break;
+ }
+ SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, CompareVT,
+ Cond, Zero,
+ True, False,
+ DAG.getCondCode(CCOpcode));
+ return DAG.getNode(ISD::BITCAST, DL, VT, SelectNode);
+ }
+
+ // Try to lower to a SET* instruction:
// We need all the operands of SELECT_CC to have the same value type, so if
// necessary we need to change True and False to be the same type as LHS and
// RHS, and then convert the result of the select_cc back to the correct type.
@@ -592,48 +642,6 @@
if (isHWTrueValue(False) && isHWFalseValue(True)) {
}
- // Check if we can lower this to a native operation.
- // CND* instructions requires all operands to have the same type,
- // and RHS to be zero.
-
- if (isZero(LHS) || isZero(RHS)) {
- SDValue Cond = (isZero(LHS) ? RHS : LHS);
- SDValue Zero = (isZero(LHS) ? LHS : RHS);
- ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
- if (CompareVT != VT) {
- True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True);
- False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False);
- }
- if (isZero(LHS)) {
- CCOpcode = ISD::getSetCCSwappedOperands(CCOpcode);
- }
-
- switch (CCOpcode) {
- case ISD::SETONE:
- case ISD::SETUNE:
- case ISD::SETNE:
- case ISD::SETULE:
- case ISD::SETULT:
- case ISD::SETOLE:
- case ISD::SETOLT:
- case ISD::SETLE:
- case ISD::SETLT:
- CCOpcode = ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32);
- Temp = True;
- True = False;
- False = Temp;
- break;
- default:
- break;
- }
- SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, CompareVT,
- Cond, Zero,
- True, False,
- DAG.getCondCode(CCOpcode));
- return DAG.getNode(ISD::BITCAST, DL, VT, SelectNode);
- }
-
-
// If we make it this for it means we have no native instructions to handle
// this SELECT_CC, so we must lower it.
SDValue HWTrue, HWFalse;
Added: llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll?rev=165527&view=auto
==============================================================================
--- llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll (added)
+++ llvm/branches/R600/test/CodeGen/R600/fcmp-cnde-int-args.ll Tue Oct 9 13:49:05 2012
@@ -0,0 +1,16 @@
+;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s
+
+; This test checks a bug in R600TargetLowering::LowerSELECT_CC where the
+; chance to optimize the fcmp + select instructions to CNDE was missed
+; due to the fact that the operands to fcmp and select had different types
+
+;CHECK: CNDE T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
+
+define void @test(i32 addrspace(1)* %out, float addrspace(1)* %in) {
+entry:
+ %0 = load float addrspace(1)* %in
+ %cmp = fcmp oeq float %0, 0.000000e+00
+ %value = select i1 %cmp, i32 -1, i32 0
+ store i32 %value, i32 addrspace(1)* %out
+ ret void
+}
More information about the llvm-branch-commits
mailing list