From ae3ffba4667b85514cf35e2efce95834ede42110 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 17 Jan 2005 17:49:14 +0000 Subject: [PATCH] Fix a major regression last night that prevented us from producing [mem] op= reg operations. The body of the if is less indented but unmodified in this patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19638 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelPattern.cpp | 220 +++++++++++++++--------------- 1 file changed, 111 insertions(+), 109 deletions(-) diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp index 5f98524c552..0ec9f3c0204 100644 --- a/lib/Target/X86/X86ISelPattern.cpp +++ b/lib/Target/X86/X86ISelPattern.cpp @@ -2489,128 +2489,130 @@ void ISel::Select(SDOperand N) { // Check to see if this is a load/op/store combination. if (N.getOperand(1).Val->hasOneUse() && + N.getOperand(0).getOpcode() == ISD::LOAD && N.getOperand(1).Val->getNumOperands() == 2 && - !MVT::isFloatingPoint(N.getOperand(0).getValue(0).getValueType()) && - isFoldableLoad(N.getOperand(0).getValue(0), - N.getOperand(0).getValue(1))) { + !MVT::isFloatingPoint(N.getOperand(0).getValue(0).getValueType())) { SDOperand TheLoad = N.getOperand(0).getValue(0); + + // See if the stored value is a simple binary operator that uses the load + // as one of its operands. + SDOperand Op = N.getOperand(1); + // Check to see if we are loading the same pointer that we're storing to. - if (TheLoad.getOperand(1) == N.getOperand(2)) { - // See if the stored value is a simple binary operator that uses the - // load as one of its operands. - SDOperand Op = N.getOperand(1); - if ((Op.getOperand(0) == TheLoad || Op.getOperand(1) == TheLoad)) { - // Finally, check to see if this is one of the ops we can handle! - static const unsigned ADDTAB[] = { - X86::ADD8mi, X86::ADD16mi, X86::ADD32mi, - X86::ADD8mr, X86::ADD16mr, X86::ADD32mr, - }; - static const unsigned SUBTAB[] = { - X86::SUB8mi, X86::SUB16mi, X86::SUB32mi, - X86::SUB8mr, X86::SUB16mr, X86::SUB32mr, - }; - static const unsigned ANDTAB[] = { - X86::AND8mi, X86::AND16mi, X86::AND32mi, - X86::AND8mr, X86::AND16mr, X86::AND32mr, - }; - static const unsigned ORTAB[] = { - X86::OR8mi, X86::OR16mi, X86::OR32mi, - X86::OR8mr, X86::OR16mr, X86::OR32mr, - }; - static const unsigned XORTAB[] = { - X86::XOR8mi, X86::XOR16mi, X86::XOR32mi, - X86::XOR8mr, X86::XOR16mr, X86::XOR32mr, - }; - static const unsigned SHLTAB[] = { - X86::SHL8mi, X86::SHL16mi, X86::SHL32mi, - /*Have to put the reg in CL*/0, 0, 0, - }; - static const unsigned SARTAB[] = { - X86::SAR8mi, X86::SAR16mi, X86::SAR32mi, - /*Have to put the reg in CL*/0, 0, 0, - }; - static const unsigned SHRTAB[] = { - X86::SHR8mi, X86::SHR16mi, X86::SHR32mi, - /*Have to put the reg in CL*/0, 0, 0, - }; - - const unsigned *TabPtr = 0; - switch (Op.getOpcode()) { - default: std::cerr << "CANNOT [mem] op= val: "; Op.Val->dump(); std::cerr << "\n"; break; - case ISD::MUL: - case ISD::SDIV: - case ISD::UDIV: - case ISD::SREM: - case ISD::UREM: break; - - case ISD::ADD: TabPtr = ADDTAB; break; - case ISD::SUB: TabPtr = SUBTAB; break; - case ISD::AND: TabPtr = ANDTAB; break; - case ISD:: OR: TabPtr = ORTAB; break; - case ISD::XOR: TabPtr = XORTAB; break; - case ISD::SHL: TabPtr = SHLTAB; break; - case ISD::SRA: TabPtr = SARTAB; break; - case ISD::SRL: TabPtr = SHRTAB; break; - } + if (TheLoad.getOperand(1) == N.getOperand(2) && + ((Op.getOperand(0) == TheLoad && + isFoldableLoad(TheLoad, Op.getOperand(1))) || + (Op.getOperand(1) == TheLoad && + isFoldableLoad(TheLoad, Op.getOperand(0))))) { + // Finally, check to see if this is one of the ops we can handle! + static const unsigned ADDTAB[] = { + X86::ADD8mi, X86::ADD16mi, X86::ADD32mi, + X86::ADD8mr, X86::ADD16mr, X86::ADD32mr, + }; + static const unsigned SUBTAB[] = { + X86::SUB8mi, X86::SUB16mi, X86::SUB32mi, + X86::SUB8mr, X86::SUB16mr, X86::SUB32mr, + }; + static const unsigned ANDTAB[] = { + X86::AND8mi, X86::AND16mi, X86::AND32mi, + X86::AND8mr, X86::AND16mr, X86::AND32mr, + }; + static const unsigned ORTAB[] = { + X86::OR8mi, X86::OR16mi, X86::OR32mi, + X86::OR8mr, X86::OR16mr, X86::OR32mr, + }; + static const unsigned XORTAB[] = { + X86::XOR8mi, X86::XOR16mi, X86::XOR32mi, + X86::XOR8mr, X86::XOR16mr, X86::XOR32mr, + }; + static const unsigned SHLTAB[] = { + X86::SHL8mi, X86::SHL16mi, X86::SHL32mi, + /*Have to put the reg in CL*/0, 0, 0, + }; + static const unsigned SARTAB[] = { + X86::SAR8mi, X86::SAR16mi, X86::SAR32mi, + /*Have to put the reg in CL*/0, 0, 0, + }; + static const unsigned SHRTAB[] = { + X86::SHR8mi, X86::SHR16mi, X86::SHR32mi, + /*Have to put the reg in CL*/0, 0, 0, + }; + + const unsigned *TabPtr = 0; + switch (Op.getOpcode()) { + default: std::cerr << "CANNOT [mem] op= val: "; Op.Val->dump(); std::cerr << "\n"; break; + case ISD::MUL: + case ISD::SDIV: + case ISD::UDIV: + case ISD::SREM: + case ISD::UREM: break; + + case ISD::ADD: TabPtr = ADDTAB; break; + case ISD::SUB: TabPtr = SUBTAB; break; + case ISD::AND: TabPtr = ANDTAB; break; + case ISD:: OR: TabPtr = ORTAB; break; + case ISD::XOR: TabPtr = XORTAB; break; + case ISD::SHL: TabPtr = SHLTAB; break; + case ISD::SRA: TabPtr = SARTAB; break; + case ISD::SRL: TabPtr = SHRTAB; break; + } - if (TabPtr) { - // Handle: [mem] op= CST - SDOperand Op0 = Op.getOperand(0); - SDOperand Op1 = Op.getOperand(1); - if (ConstantSDNode *CN = dyn_cast(Op1)) { - switch (Op0.getValueType()) { // Use Op0's type because of shifts. - default: break; - case MVT::i1: - case MVT::i8: Opc = TabPtr[0]; break; - case MVT::i16: Opc = TabPtr[1]; break; - case MVT::i32: Opc = TabPtr[2]; break; - } - - if (Opc) { - if (getRegPressure(TheLoad.getOperand(0)) > - getRegPressure(TheLoad.getOperand(1))) { - Select(TheLoad.getOperand(0)); - SelectAddress(TheLoad.getOperand(1), AM); - } else { - SelectAddress(TheLoad.getOperand(1), AM); - Select(TheLoad.getOperand(0)); - } - - addFullAddress(BuildMI(BB, Opc, 4+1),AM).addImm(CN->getValue()); - return; - } + if (TabPtr) { + // Handle: [mem] op= CST + SDOperand Op0 = Op.getOperand(0); + SDOperand Op1 = Op.getOperand(1); + if (ConstantSDNode *CN = dyn_cast(Op1)) { + switch (Op0.getValueType()) { // Use Op0's type because of shifts. + default: break; + case MVT::i1: + case MVT::i8: Opc = TabPtr[0]; break; + case MVT::i16: Opc = TabPtr[1]; break; + case MVT::i32: Opc = TabPtr[2]; break; } - - // If we have [mem] = V op [mem], try to turn it into: - // [mem] = [mem] op V. - if (Op1 == TheLoad && Op.getOpcode() != ISD::SUB && - Op.getOpcode() != ISD::SHL && Op.getOpcode() != ISD::SRA && - Op.getOpcode() != ISD::SRL) - std::swap(Op0, Op1); - - if (Op0 == TheLoad) { - switch (Op0.getValueType()) { - default: break; - case MVT::i1: - case MVT::i8: Opc = TabPtr[3]; break; - case MVT::i16: Opc = TabPtr[4]; break; - case MVT::i32: Opc = TabPtr[5]; break; - } - - if (Opc) { + + if (Opc) { + if (getRegPressure(TheLoad.getOperand(0)) > + getRegPressure(TheLoad.getOperand(1))) { Select(TheLoad.getOperand(0)); SelectAddress(TheLoad.getOperand(1), AM); - unsigned Reg = SelectExpr(Op1); - addFullAddress(BuildMI(BB, Opc, 4+1),AM).addReg(Reg); - return; - } + } else { + SelectAddress(TheLoad.getOperand(1), AM); + Select(TheLoad.getOperand(0)); + } + + addFullAddress(BuildMI(BB, Opc, 4+1),AM).addImm(CN->getValue()); + return; + } + } + + // If we have [mem] = V op [mem], try to turn it into: + // [mem] = [mem] op V. + if (Op1 == TheLoad && Op.getOpcode() != ISD::SUB && + Op.getOpcode() != ISD::SHL && Op.getOpcode() != ISD::SRA && + Op.getOpcode() != ISD::SRL) + std::swap(Op0, Op1); + + if (Op0 == TheLoad) { + switch (Op0.getValueType()) { + default: break; + case MVT::i1: + case MVT::i8: Opc = TabPtr[3]; break; + case MVT::i16: Opc = TabPtr[4]; break; + case MVT::i32: Opc = TabPtr[5]; break; + } + + if (Opc) { + Select(TheLoad.getOperand(0)); + SelectAddress(TheLoad.getOperand(1), AM); + unsigned Reg = SelectExpr(Op1); + addFullAddress(BuildMI(BB, Opc, 4+1),AM).addReg(Reg); + return; } } } } } - switch (N.getOperand(1).getValueType()) { default: assert(0 && "Cannot store this type!"); case MVT::i1: -- 2.34.1