llvm.org GIT mirror llvm / 730a570
Re-write the address propagation code for pre-indexed loads/stores to take into account some previously misssed cases (PRE_DEC addressing mode, the offset and base address are swapped, etc). This should fix PR15581. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180609 91177308-0d34-0410-b5e6-96231b3b80d8 Silviu Baranga 7 years ago
1 changed file(s) with 31 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
71517151 assert(OtherUses[i]->getOperand(!OffsetIdx).getNode() ==
71527152 BasePtr.getNode() && "Expected BasePtr operand");
71537153
7154 APInt OV =
7155 cast(Offset)->getAPIntValue();
7156 if (AM == ISD::PRE_DEC)
7157 OV = -OV;
7154 // We need to replace ptr0 in the following expression:
7155 // x0 * offset0 + y0 * ptr0 = t0
7156 // knowing that
7157 // x1 * offset1 + y1 * ptr0 = t1 (the indexed load/store)
7158 //
7159 // where x0, x1, y0 and y1 in {-1, 1} are given by the types of the
7160 // indexed load/store and the expresion that needs to be re-written.
7161 //
7162 // Therefore, we have:
7163 // t0 = (x0 * offset0 - x1 * y0 * y1 *offset1) + (y0 * y1) * t1
71587164
71597165 ConstantSDNode *CN =
71607166 cast(OtherUses[i]->getOperand(OffsetIdx));
7161 APInt CNV = CN->getAPIntValue();
7162 if (OtherUses[i]->getOpcode() == ISD::SUB && OffsetIdx == 1)
7163 CNV += OV;
7164 else
7165 CNV -= OV;
7166
7167 SDValue NewOp1 = Result.getValue(isLoad ? 1 : 0);
7168 SDValue NewOp2 = DAG.getConstant(CNV, CN->getValueType(0));
7169 if (OffsetIdx == 0)
7170 std::swap(NewOp1, NewOp2);
7171
7172 SDValue NewUse = DAG.getNode(OtherUses[i]->getOpcode(),
7167 int X0, X1, Y0, Y1;
7168 APInt Offset0 = CN->getAPIntValue();
7169 APInt Offset1 = cast(Offset)->getAPIntValue();
7170
7171 X0 = (OtherUses[i]->getOpcode() == ISD::SUB && OffsetIdx == 1) ? -1 : 1;
7172 Y0 = (OtherUses[i]->getOpcode() == ISD::SUB && OffsetIdx == 0) ? -1 : 1;
7173 X1 = (AM == ISD::PRE_DEC && !Swapped) ? -1 : 1;
7174 Y1 = (AM == ISD::PRE_DEC && Swapped) ? -1 : 1;
7175
7176 unsigned Opcode = (Y0 * Y1 < 0) ? ISD::SUB : ISD::ADD;
7177
7178 APInt CNV = Offset0;
7179 if (X0 < 0) CNV = -CNV;
7180 if (X1 * Y0 * Y1 < 0) CNV = CNV + Offset1;
7181 else CNV = CNV - Offset1;
7182
7183 // We can now generate the new expression.
7184 SDValue NewOp1 = DAG.getConstant(CNV, CN->getValueType(0));
7185 SDValue NewOp2 = Result.getValue(isLoad ? 1 : 0);
7186
7187 SDValue NewUse = DAG.getNode(Opcode,
71737188 OtherUses[i]->getDebugLoc(),
71747189 OtherUses[i]->getValueType(0), NewOp1, NewOp2);
71757190 DAG.ReplaceAllUsesOfValueWith(SDValue(OtherUses[i], 0), NewUse);