Splitting a load with 2 consumers into 2 loads.

Hi, I am writing an llvm target and I need both loads for isel reasons, but I am struggling to find the right way. I have been trying to use DAG.getLoad() to make a copy, then just change the operand in the consumers, but I cannot seem to get all of the arguments needed for that function in order to make the copy. Any help would be great, thanks!

So I think I have made some progress.

SDValue dupVal = consumer->getOperand(OpNo);
LoadSDNode dupNode = (LoadSDNode) dupVal.getNode();

SDValue newLoad = CurDAG->getLoad(dupVal.getValueType(), dupVal.getDebugLoc(),
dupVal.getOperand(0), dupVal.getOperand(1),
dupNode->isVolatile(), dupNode->isNonTemporal(),
dupNode->isInvariant(), dupNode->getAlignment(),
dupNode->getTBAAInfo(), dupNode->getRanges());
However, my problem now is that it will re-use the same load still. If I change something, like setting volatile to true for example, it will create a new node, but otherwise it will not. Any ideas?

Hi, Joseph, I guess getLoad() will either search an existed SDValue
*OR* create a new one for a non-existed one depending on real

Since you use exactly the same attributes dupVal/dupNode have, no
doubt getLoad() return the old one.

I am not sure it's *volatile* that let you get a new result, you might
want to try change some other parameters and check what it turns out.


Yes, changing parameters will create a new Node, but is there some way I can force a new node with the same parameters?

Hi, Joe.

I am sorry I did not catch your point. Can you provide more details?

Since SDValue/SDNode can be used multiple times, why would you want to
create two identical objects
instead of reference to the same one?

I am writing a target for an odd cisc-like architecture which has no support for keeping most values in registers. As such, memory-memory operations are needed, but for isel to generate a memory-memory the pattern must be of the form (store (op (load) (load))).

Let’s use a simple example to show how this can be problematic:

%0 = load i32* %a.addr, align 4
store i32 %0, i32* %other, align 4

%1 = load i32* %b.addr, align 4
%add = add i32 %0, %1

OK, I get it.

The essence of this problem is that a node can be covered exactly and
just once but its result can be referred multiple times for a tree
pattern matching isel. So to duplicate a load node (only if we can!)
is convenient to conquer that case.

The truth is, in pattern (add (load) (load)), source operands are
memory addresses, and thus it can be treated as (addmm
address, address). Here is an alternative you can take into
consideration: defining new node (like addmm, similiar with movmm) to
specify matching patterns for isel.


I’ll give that a shot, thanks!

This worked perfectly. Thankyou.