diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index f58ca60ed9f..422b1959159 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -392,6 +392,30 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM, } break; } + + case ISD::OR: { + if (!Available) { + X86ISelAddressMode Backup = AM; + // Look for (x << c1) | c2 where (c2 < c1) + ConstantSDNode *CN = dyn_cast(N.Val->getOperand(0)); + if (CN && !MatchAddress(N.Val->getOperand(1), AM, false)) { + if (AM.GV == NULL && AM.Disp == 0 && CN->getValue() < AM.Scale) { + AM.Disp = CN->getValue(); + return false; + } + } + AM = Backup; + CN = dyn_cast(N.Val->getOperand(1)); + if (CN && !MatchAddress(N.Val->getOperand(0), AM, false)) { + if (AM.GV == NULL && AM.Disp == 0 && CN->getValue() < AM.Scale) { + AM.Disp = CN->getValue(); + return false; + } + } + AM = Backup; + } + break; + } } // Is the base register already occupied? diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index de1c3a1ff49..d222bead62f 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -133,7 +133,7 @@ def brtarget : Operand; // Define X86 specific addressing mode. def addr : ComplexPattern; def leaaddr : ComplexPattern; + [add, mul, shl, or, frameindex]>; //===----------------------------------------------------------------------===// // X86 Instruction Format Definitions.