Kazushi Marukawa via llvm-dev
2019-Mar-05 00:03 UTC
[llvm-dev] ADD frameindex, constant conbined to OR
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