[llvm-dev] llvm combines "ADD frameindex, constant" to OR
Kazushi Marukawa via llvm-dev
llvm-dev at lists.llvm.org
Tue Mar 12 17:24:57 PDT 2019
Hi all,
I've been working on a backend of our architecture and noticed llvm performs
following combining although one of operands is FrameIndex.
Combining: t114: i64 = add FrameIndex:i64<0>, Constant:i64<56>
Creating new node: t121: i64 = or FrameIndex:i64<0>, Constant:i64<56>
... into: t121: i64 = or FrameIndex:i64<0>, Constant:i64<56>
This caused problem if frame pointer points 0x60000038 at run time.
I checked DAGCombiner::visitADD. It folds ADD to OR by following code
without considering about FrameIndex. This haveNoCommonBitsSet says
it's safe since FrameIndex(0) is 0.
// fold (a+b) -> (a|b) iff a and b share no bits.
if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) &&
DAG.haveNoCommonBitsSet(N0, N1))
return DAG.getNode(ISD::OR, DL, VT, N0, N1);
I checked visitADD more and find that it performs some kind of undo
like bellow if the input is (+ (+ FI <const>) <const>).
// Undo the add -> or combine to merge constant offsets from a frame index.
if (N0.getOpcode() == ISD::OR &&
isa<FrameIndexSDNode>(N0.getOperand(0)) &&
isa<ConstantSDNode>(N0.getOperand(1)) &&
DAG.haveNoCommonBitsSet(N0.getOperand(0), N0.getOperand(1))) {
SDValue Add0 = DAG.getNode(ISD::ADD, DL, VT, N1, N0.getOperand(1));
return DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(0), Add0);
}
I think this code may work fine on an architecture using FI + A + B.
However, our architecture seems to use only FI + A and this ADD is
converted to OR permanently. As a result, generated code use OR and
it causes run time error depends on the address of frame pointer.
I also checked visitOR, but I cannot find any undoing there.
My question is:
1. Is there any way to control this to avoid OR folding,
like TargetLowering::preferNotCombineToOrFrameIndex?
(or should we add new?)
2. How to optimize FrameIndex? I desire DAGCombiner use alignment
information on data, stack frame, or something.
Best Regards,
-- Kazushi
More information about the llvm-dev
mailing list