Author: clamb Date: Fri Aug 10 16:48:46 2007 New Revision: 41010 URL: http://llvm.org/viewvc/llvm-project?rev=41010&view=rev Log: Increase efficiency of sign_extend_inreg by using subregisters for truncation. As the README suggests sign_extend_subreg is selected to (sext(trunc)).
Added: llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll Modified: llvm/trunk/lib/Target/X86/README.txt llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/test/CodeGen/X86/shl_elim.ll Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=41010&r1=41009&r2=41010&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Fri Aug 10 16:48:46 2007 @@ -473,21 +473,6 @@ //===---------------------------------------------------------------------===// -Bad codegen: - -char foo(int x) { return x; } - -_foo: - movl 4(%esp), %eax - shll $24, %eax - sarl $24, %eax - ret - -SIGN_EXTEND_INREG can be implemented as (sext (trunc)) to take advantage of -sub-registers. - -//===---------------------------------------------------------------------===// - Consider this: typedef struct pair { float A, B; } pair; Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=41010&r1=41009&r2=41010&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Aug 10 16:48:46 2007 @@ -208,6 +208,10 @@ /// base register. Return the virtual register that holds this value. SDNode *getGlobalBaseReg(); + /// getTruncate - return an SDNode that implements a subreg based truncate + /// of the specified operand to the the specified value type. + SDNode *getTruncate(SDOperand N0, MVT::ValueType VT); + #ifndef NDEBUG unsigned Indent; #endif @@ -979,6 +983,44 @@ return FindCallStartFromCall(Node->getOperand(0).Val); } +SDNode *X86DAGToDAGISel::getTruncate(SDOperand N0, MVT::ValueType VT) { + SDOperand SRIdx; + switch (VT) { + case MVT::i8: + SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1 + // Ensure that the source register has an 8-bit subreg on 32-bit targets + if (!Subtarget->is64Bit()) { + unsigned Opc; + MVT::ValueType VT; + switch (N0.getValueType()) { + default: assert(0 && "Unknown truncate!"); + case MVT::i16: + Opc = X86::MOV16to16_; + VT = MVT::i16; + break; + case MVT::i32: + Opc = X86::MOV32to32_; + VT = MVT::i32; + break; + } + N0 = + SDOperand(CurDAG->getTargetNode(Opc, VT, N0), 0); + } + break; + case MVT::i16: + SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2 + break; + case MVT::i32: + SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3 + break; + default: assert(0 && "Unknown truncate!"); + } + return CurDAG->getTargetNode(X86::EXTRACT_SUBREG, + VT, + N0, SRIdx); +} + + SDNode *X86DAGToDAGISel::Select(SDOperand N) { SDNode *Node = N.Val; MVT::ValueType NVT = Node->getValueType(0); @@ -1330,44 +1372,57 @@ return NULL; } + + case ISD::SIGN_EXTEND_INREG: { + SDOperand N0 = Node->getOperand(0); + AddToISelQueue(N0); - case ISD::TRUNCATE: { - SDOperand Tmp; - SDOperand Input = Node->getOperand(0); - AddToISelQueue(Node->getOperand(0)); + MVT::ValueType SVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); + SDOperand TruncOp = SDOperand(getTruncate(N0, SVT), 0); + unsigned Opc; switch (NVT) { - case MVT::i8: - Tmp = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1 - // Ensure that the source register has an 8-bit subreg on 32-bit targets - if (!Subtarget->is64Bit()) { - unsigned Opc; - MVT::ValueType VT; - switch (Node->getOperand(0).getValueType()) { - default: assert(0 && "Unknown truncate!"); - case MVT::i16: - Opc = X86::MOV16to16_; - VT = MVT::i16; - break; - case MVT::i32: - Opc = X86::MOV32to32_; - VT = MVT::i32; - break; - } - Input = - SDOperand(CurDAG->getTargetNode(Opc, VT, Node->getOperand(0)), 0); - } - break; case MVT::i16: - Tmp = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2 + if (SVT == MVT::i8) Opc = X86::MOVSX16rr8; + else assert(0 && "Unknown sign_extend_inreg!"); break; case MVT::i32: - Tmp = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3 + switch (SVT) { + case MVT::i8: Opc = X86::MOVSX32rr8; break; + case MVT::i16: Opc = X86::MOVSX32rr16; break; + default: assert(0 && "Unknown sign_extend_inreg!"); + } + break; + case MVT::i64: + switch (SVT) { + case MVT::i8: Opc = X86::MOVSX64rr8; break; + case MVT::i16: Opc = X86::MOVSX64rr16; break; + case MVT::i32: Opc = X86::MOVSX64rr32; break; + default: assert(0 && "Unknown sign_extend_inreg!"); + } break; - default: assert(0 && "Unknown truncate!"); + default: assert(0 && "Unknown sign_extend_inreg!"); } - SDNode *ResNode = CurDAG->getTargetNode(X86::EXTRACT_SUBREG, - NVT, - Input, Tmp); + + SDNode *ResNode = CurDAG->getTargetNode(Opc, NVT, TruncOp); + +#ifndef NDEBUG + DOUT << std::string(Indent-2, ' ') << "=> "; + DEBUG(TruncOp.Val->dump(CurDAG)); + DOUT << "\n"; + DOUT << std::string(Indent-2, ' ') << "=> "; + DEBUG(ResNode->dump(CurDAG)); + DOUT << "\n"; + Indent -= 2; +#endif + return ResNode; + break; + } + + case ISD::TRUNCATE: { + SDOperand Input = Node->getOperand(0); + AddToISelQueue(Node->getOperand(0)); + SDNode *ResNode = getTruncate(Input, NVT); + #ifndef NDEBUG DOUT << std::string(Indent-2, ' ') << "=> "; DEBUG(ResNode->dump(CurDAG)); Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=41010&r1=41009&r2=41010&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Aug 10 16:48:46 2007 @@ -157,9 +157,9 @@ setOperationAction(ISD::SELECT_CC , MVT::Other, Expand); setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); if (Subtarget->is64Bit()) - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Expand); - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); - setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Legal); + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Legal); + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Legal); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); setOperationAction(ISD::FREM , MVT::f64 , Expand); Added: llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll?rev=41010&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll (added) +++ llvm/trunk/test/CodeGen/X86/2007-08-10-SignExtSubreg.ll Fri Aug 10 16:48:46 2007 @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {movsbl .al, .eax} + [EMAIL PROTECTED] = global i32 0 ; <i32*> [#uses=1] + +define i8 @_Z3fooi(i32 %x) signext { +entry: + store i32 %x, i32* @X, align 4 + %retval67 = trunc i32 %x to i8 ; <i8> [#uses=1] + ret i8 %retval67 +} \ No newline at end of file Modified: llvm/trunk/test/CodeGen/X86/shl_elim.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/shl_elim.ll?rev=41010&r1=41009&r2=41010&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/shl_elim.ll (original) +++ llvm/trunk/test/CodeGen/X86/shl_elim.ll Fri Aug 10 16:48:46 2007 @@ -1,6 +1,6 @@ ; RUN: llvm-as < %s | llc -march=x86 | grep {movl 8(.esp), %eax} -; RUN: llvm-as < %s | llc -march=x86 | grep {shll .15, .eax} -; RUN: llvm-as < %s | llc -march=x86 | grep {sarl .16, .eax} +; RUN: llvm-as < %s | llc -march=x86 | grep {shrl .eax} +; RUN: llvm-as < %s | llc -march=x86 | grep {movswl .ax, .eax} define i32 @test1(i64 %a) { %tmp29 = lshr i64 %a, 24 ; <i64> [#uses=1] _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits