# ADD frameindex, constant conbined to OR

**URL:** <https://discourse.llvm.org/t/add-frameindex-constant-conbined-to-or/51342>\
**Category:** LLVM Dev List Archives\
**Created:** [March 5, 2019, 12:03am UTC](https://discourse.llvm.org/t/add-frameindex-constant-conbined-to-or/51342 "2019-03-05T00:03:38Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kazushi\_Marukawa](https://avatars.discourse-cdn.com/v4/letter/k/e8c25b/32.png) [@Kazushi\_Marukawa](https://discourse.llvm.org/u/Kazushi_Marukawa)\
**Post date:** [March 5, 2019, 12:03am UTC](https://discourse.llvm.org/t/add-frameindex-constant-conbined-to-or/51342/1 "2019-03-05T00:03:38Z")

</div>

Hi all,

I've been working on a backend of our architecture and noticed llvm performs  
following combining although one of operands is FrameIndex.

&nbsp;&nbsp;&nbsp;&nbsp;Combining: t114: i64 = add FrameIndex:i64\<0\>, Constant:i64\<56\>  
&nbsp;&nbsp;&nbsp;&nbsp;Creating new node: t121: i64 = or FrameIndex:i64\<0\>, Constant:i64\<56\>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... 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...

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// fold (a+b) -\> (a|b) iff a and b share no bits.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) &&  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DAG.haveNoCommonBitsSet(N0, N1))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return DAG.getNode(ISD::OR, DL, VT, N0, N1);

The visitADD also performs some kind of undo like bellow.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Undo the add -\> or combine to merge constant offsets from a frame index.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (N0.getOpcode() == ISD::OR &&  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isa\<FrameIndexSDNode\>(N0.getOperand(0)) &&  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isa\<ConstantSDNode\>(N0.getOperand(1)) &&  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DAG.haveNoCommonBitsSet(N0.getOperand(0), N0.getOperand(1))) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SDValue Add0 = DAG.getNode(ISD::ADD, DL, VT, N1, N0.getOperand(1));  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(0), Add0);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

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:

&nbsp;&nbsp;1. Is there any way to control this to avoid OR folding,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;like TargetLowering::preferNotCombineToOrFrameIndex?  
&nbsp;&nbsp;2. How to optimize FrameIndex? I desire DAGCombiner use alignment  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;information on FrameIndex.

Best Regards,  
-- Kazushi
