[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp
Chris Lattner
lattner at cs.uiuc.edu
Wed Jan 19 00:07:19 PST 2005
Changes in directory llvm/lib/Target/X86:
X86ISelPattern.cpp updated: 1.79 -> 1.80
---
Log message:
Implement Regression/CodeGen/X86/rotate.ll: emit rotate instructions (which
typically cost 1 cycle) instead of shld/shrd instruction (which are typically
6 or more cycles). This also saves code space.
For example, instead of emitting:
rotr:
mov %EAX, DWORD PTR [%ESP + 4]
mov %CL, BYTE PTR [%ESP + 8]
shrd %EAX, %EAX, %CL
ret
rotli:
mov %EAX, DWORD PTR [%ESP + 4]
shrd %EAX, %EAX, 27
ret
Emit:
rotr32:
mov %CL, BYTE PTR [%ESP + 8]
mov %EAX, DWORD PTR [%ESP + 4]
ror %EAX, %CL
ret
rotli32:
mov %EAX, DWORD PTR [%ESP + 4]
ror %EAX, 27
ret
We also emit byte rotate instructions which do not have a sh[lr]d counterpart
at all.
---
Diffs of the changes: (+79 -38)
Index: llvm/lib/Target/X86/X86ISelPattern.cpp
diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.79 llvm/lib/Target/X86/X86ISelPattern.cpp:1.80
--- llvm/lib/Target/X86/X86ISelPattern.cpp:1.79 Wed Jan 19 01:37:26 2005
+++ llvm/lib/Target/X86/X86ISelPattern.cpp Wed Jan 19 02:07:05 2005
@@ -1165,47 +1165,60 @@
// Find out if ShrAmt = 32-ShlAmt or ShlAmt = 32-ShrAmt.
if (ShlAmt.getOpcode() == ISD::SUB && ShlAmt.getOperand(1) == ShrAmt)
if (ConstantSDNode *SubCST = dyn_cast<ConstantSDNode>(ShlAmt.getOperand(0)))
- if (SubCST->getValue() == RegSize && RegSize != 8) {
+ if (SubCST->getValue() == RegSize) {
+ // (A >> ShrAmt) | (A << (32-ShrAmt)) ==> ROR A, ShrAmt
// (A >> ShrAmt) | (B << (32-ShrAmt)) ==> SHRD A, B, ShrAmt
- unsigned AReg, BReg;
- if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) {
- AReg = SelectExpr(ShrVal);
- BReg = SelectExpr(ShlVal);
- } else {
- BReg = SelectExpr(ShlVal);
- AReg = SelectExpr(ShrVal);
+ if (ShrVal == ShlVal) {
+ unsigned Reg, ShAmt;
+ if (getRegPressure(ShrVal) > getRegPressure(ShrAmt)) {
+ Reg = SelectExpr(ShrVal);
+ ShAmt = SelectExpr(ShrAmt);
+ } else {
+ ShAmt = SelectExpr(ShrAmt);
+ Reg = SelectExpr(ShrVal);
+ }
+ BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt);
+ unsigned Opc = RegSize == 8 ? X86::ROR8rCL :
+ (RegSize == 16 ? X86::ROR16rCL : X86::ROR32rCL);
+ BuildMI(BB, Opc, 1, DestReg).addReg(Reg);
+ return true;
+ } else if (RegSize != 8) {
+ unsigned AReg, BReg;
+ if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) {
+ AReg = SelectExpr(ShrVal);
+ BReg = SelectExpr(ShlVal);
+ } else {
+ BReg = SelectExpr(ShlVal);
+ AReg = SelectExpr(ShrVal);
+ }
+ unsigned ShAmt = SelectExpr(ShrAmt);
+ BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt);
+ unsigned Opc = RegSize == 16 ? X86::SHRD16rrCL : X86::SHRD32rrCL;
+ BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg);
+ return true;
}
- unsigned ShAmt = SelectExpr(ShrAmt);
- BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt);
- unsigned Opc = RegSize == 16 ? X86::SHRD16rrCL : X86::SHRD32rrCL;
- BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg);
- return true;
}
if (ShrAmt.getOpcode() == ISD::SUB && ShrAmt.getOperand(1) == ShlAmt)
if (ConstantSDNode *SubCST = dyn_cast<ConstantSDNode>(ShrAmt.getOperand(0)))
- if (SubCST->getValue() == RegSize && RegSize != 8) {
+ if (SubCST->getValue() == RegSize) {
+ // (A << ShlAmt) | (A >> (32-ShlAmt)) ==> ROL A, ShrAmt
// (A << ShlAmt) | (B >> (32-ShlAmt)) ==> SHLD A, B, ShrAmt
- unsigned AReg, BReg;
- if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) {
- AReg = SelectExpr(ShrVal);
- BReg = SelectExpr(ShlVal);
- } else {
- BReg = SelectExpr(ShlVal);
- AReg = SelectExpr(ShrVal);
- }
- unsigned ShAmt = SelectExpr(ShlAmt);
- BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt);
- unsigned Opc = RegSize == 16 ? X86::SHLD16rrCL : X86::SHLD32rrCL;
- BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg);
- return true;
- }
-
- if (ConstantSDNode *ShrCst = dyn_cast<ConstantSDNode>(ShrAmt))
- if (ConstantSDNode *ShlCst = dyn_cast<ConstantSDNode>(ShlAmt))
- if (ShrCst->getValue() < RegSize && ShlCst->getValue() < RegSize) {
- if (ShrCst->getValue() == RegSize-ShlCst->getValue() && RegSize != 8) {
- // (A >> 5) | (B << 27) --> SHRD A, B, 5
+ if (ShrVal == ShlVal) {
+ unsigned Reg, ShAmt;
+ if (getRegPressure(ShrVal) > getRegPressure(ShlAmt)) {
+ Reg = SelectExpr(ShrVal);
+ ShAmt = SelectExpr(ShlAmt);
+ } else {
+ ShAmt = SelectExpr(ShlAmt);
+ Reg = SelectExpr(ShrVal);
+ }
+ BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt);
+ unsigned Opc = RegSize == 8 ? X86::ROL8rCL :
+ (RegSize == 16 ? X86::ROL16rCL : X86::ROL32rCL);
+ BuildMI(BB, Opc, 1, DestReg).addReg(Reg);
+ return true;
+ } else if (RegSize != 8) {
unsigned AReg, BReg;
if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) {
AReg = SelectExpr(ShrVal);
@@ -1214,14 +1227,42 @@
BReg = SelectExpr(ShlVal);
AReg = SelectExpr(ShrVal);
}
- unsigned Opc = RegSize == 16 ? X86::SHRD16rri8 : X86::SHRD32rri8;
- BuildMI(BB, Opc, 3, DestReg).addReg(AReg).addReg(BReg)
- .addImm(ShrCst->getValue());
+ unsigned ShAmt = SelectExpr(ShlAmt);
+ BuildMI(BB, X86::MOV8rr, 1, X86::CL).addReg(ShAmt);
+ unsigned Opc = RegSize == 16 ? X86::SHLD16rrCL : X86::SHLD32rrCL;
+ BuildMI(BB, Opc, 2, DestReg).addReg(AReg).addReg(BReg);
return true;
}
}
-
+ if (ConstantSDNode *ShrCst = dyn_cast<ConstantSDNode>(ShrAmt))
+ if (ConstantSDNode *ShlCst = dyn_cast<ConstantSDNode>(ShlAmt))
+ if (ShrCst->getValue() < RegSize && ShlCst->getValue() < RegSize)
+ if (ShrCst->getValue() == RegSize-ShlCst->getValue()) {
+ // (A >> 5) | (A << 27) --> ROR A, 5
+ // (A >> 5) | (B << 27) --> SHRD A, B, 5
+ if (ShrVal == ShlVal) {
+ unsigned Reg = SelectExpr(ShrVal);
+ unsigned Opc = RegSize == 8 ? X86::ROR8ri :
+ (RegSize == 16 ? X86::ROR16ri : X86::ROR32ri);
+ BuildMI(BB, Opc, 2, DestReg).addReg(Reg).addImm(ShrCst->getValue());
+ return true;
+ } else if (RegSize != 8) {
+ unsigned AReg, BReg;
+ if (getRegPressure(ShlVal) > getRegPressure(ShrVal)) {
+ AReg = SelectExpr(ShrVal);
+ BReg = SelectExpr(ShlVal);
+ } else {
+ BReg = SelectExpr(ShlVal);
+ AReg = SelectExpr(ShrVal);
+ }
+ unsigned Opc = RegSize == 16 ? X86::SHRD16rri8 : X86::SHRD32rri8;
+ BuildMI(BB, Opc, 3, DestReg).addReg(AReg).addReg(BReg)
+ .addImm(ShrCst->getValue());
+ return true;
+ }
+ }
+
return false;
}
More information about the llvm-commits
mailing list