Hitting assertion, unsure why

I am hitting this assertion:

assert(I != VRBaseMap.end() && "Node emitted out of order - late");

I am not sure why this assertion is being triggered or what I changed
that is causing it.

This is asserting when SDValue is FrameIndexSDNode 1.

I don't have any code that modified frameindices until my overloaded
RegisterInfo function.

I've attached the bc file. If I generate an unoptimized bc file then
there is no issue, only when I turn optimizations on do I hit this
problem.

Thanks for any hints,

Micah Villmow

Systems Engineer

Advanced Technology & Performance

Advanced Micro Devices Inc.

S1-609 One AMD Place

Sunnyvale, CA. 94085

P: 408-749-3966

test-opt.bc (1.01 KB)

I got this too. It's related to debug information being in flux right
now. I believe that Devang is working on a fix for this right now.

-bw

Is there any known method/hack of bypassing this?

Thanks,

Don't generate debug info at this time (you can use "opt
-strip-debug")? :slight_smile: Otherwise, I'm not sure.

-bw

This did not seem to work, any other ideas?

Thanks,

Other than not using debugging ('-g' and the like), not really. :frowning: I
think that Devang is actively working on fixing this, though. It might
not be too much longer.

-bw

Ok, I've had time to track this down a little bit more and I seem to
have found another case where it fails. This is occurring during
Schedulur->EmitSchedule() in SelectionDAGISel.cpp:695. The problem seems
to be that somehow the CopyToReg part of the switch statement in
ScheduleDAG::EmitNode has a FrameIndex as its second operand. This is
especially problematic because the code is either expecting a
VirtualRegister or a RegisterSDNode in this location. I've checked all
locations where I use the DAG.getCopyToReg function and none of them
pass in a frameindex. I explcitily check that I have a register before
passing in the value to Register number to CopyToReg, so this leads me
to believe that it is being generated somehow by LLVM.

In the case I sent earlier in this thread it only occurs when I turn
optimizations on, but the new case I hit with optimizations off but
through a different method.

I've tried the strip-debug method and that doesn't seem to help, any
other ideas or tips where I can look to further debug this issue would
be very helpful.

Thanks,
Micah

StandardLinkConstraintSet.bc (644 Bytes)

Ok, I've had time to track this down a little bit more and I seem to
have found another case where it fails. This is occurring during
Schedulur->EmitSchedule() in SelectionDAGISel.cpp:695. The problem seems
to be that somehow the CopyToReg part of the switch statement in
ScheduleDAG::EmitNode has a FrameIndex as its second operand. This is
especially problematic because the code is either expecting a
VirtualRegister or a RegisterSDNode in this location. I've checked all

Unfortunately, I don't think anyone can help you until you can track down what is creating the FrameIndex. Why not set a break point in MachineFrameInfo::CreateFixedObject and CreateStackObject?

Evan

Evan,
Thanks for the tip, I was able to track down where the FrameIndex is
being created and I think I know where the problem is now.

Micah

Well, I thought I knew how to fix the problem, but it seems my changes
didn't help at all. The frame index is being created when
FuncInfo->set() is called in SelectionDAGISel::runOnFunction().
This occurs at line 293 in SelectionDAGBuild.cpp when dealing with the
alloca instructions.

I've found the CopyToReg that is being issued occurs in LowerCALL and it
is this one that fails. When I get the arguments to the function call,
(SDValue Arg = TheCall->getArg(i);), the returned SDValue is a
FrameIndex, and I don't handle the case correctly. The only issue that I
have is that none of the other backends have any code in
LowerCALL/LowerRET/LowerFORMAL_ARGUMENTS that explicitly handle
FrameIndexSDNode's as arguments. This leads me to believe that I
shouldn't have to handle this case and there is an error occurring
somewhere else and is showing up here.

My test case is fairly simple:
float func(float *a);

void test(float *positions)
{
  float linkABNorm = positions[0];
  float b = func(&linkABNorm);
    positions[0] = b * linkABNorm;
}
float func(float *a)
{
    *a = 10.0f;
    return *a;
}

The problem is linked to taking the address of the stack variable and
passing it as a pointer to another function.

So, my questions are:
1) Is there anything special I should be doing to handle a
FrameIndexSDNode being passed into LowerCALL?
2) If not, Where can I look that might show some light on what I'm doing
wrong in tablegen/ISelLowering?
3) What is the expected behavior of llvm in this case?

Thanks for any help,
Micah

The problem is linked to taking the address of the stack variable and
passing it as a pointer to another function.

This is a common optimization since the addressing is a (simple, propagated) base+offset and doesn’t require a new stack spill.

So, my questions are:

  1. Is there anything special I should be doing to handle a
    FrameIndexSDNode being passed into LowerCALL?

No. The CellSPU backend doesn’t do anything special in this regard. It just sees a MVT::i32 pointer.

  1. If not, Where can I look that might show some light on what I’m doing
    wrong in tablegen/ISelLowering?

You might need to add some code to your ISelDAGToDAG source during instruction selection to catch FrameIndex nodes and generate the instruction sequence that creates the proper base+offset pointer. What you’re likely seeing is a FrameIndex that’s used multiple times (“” when you dump the DAG) and is now higher in the DAG as a sole node.

I’m surprised, however, that you haven’t yet seen a “Cannot select …” assert.

-scooter