[llvm-commits] [llvm] r41010 - in /llvm/trunk: lib/Target/X86/README.txt lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2007-08-10-SignExtSubreg.ll test/CodeGen/X86/shl_elim.ll
Christopher Lamb
christopher.lamb at gmail.com
Fri Aug 10 14:48:46 PDT 2007
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}
+
+ at X = 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]
More information about the llvm-commits
mailing list