[llvm-dev] ADD frameindex, constant conbined to OR
Kazushi Marukawa via llvm-dev
llvm-dev at lists.llvm.org
Mon Mar 4 16:03:38 PST 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>
I checked DAGCombiner::visitADD. It folds ADD to OR here although
one operand is FrameIndex. haveNoCommonBitsSet says it's safe to
combining 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);
The visitADD also performs some kind of undo like bellow.
// 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 it is converted
to OR permanently. As a result, generated code use OR on address on
stack frame. It runs wrongly depends on the contents of SP.
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?
2. How to optimize FrameIndex? I desire DAGCombiner use alignment
information on FrameIndex.
Best Regards,
-- Kazushi
More information about the llvm-dev
mailing list