Proposed modification of AsmPrinter::EmitConstantValueOnly()

I have a problem (bug 2672) in which I have a static initializer that contains a GEP. The GEP itself has arguments that do casts and another GEP.

This fails in EmitConstantValueOnly() because the GEP arguments are not recognized as constant (link time) expressions.

It looks to me that a proper solution could be to make EmitConstantValueOnly() return its constant value and call it for each argument of the GEP which will then be passed to getIndexedOffset().

Does this sound like a reasonable solution?

-Rich

Richard Pennington wrote:

I have a problem (bug 2672) in which I have a static initializer that contains a GEP. The GEP itself has arguments that do casts and another GEP.

This fails in EmitConstantValueOnly() because the GEP arguments are not recognized as constant (link time) expressions.

It looks to me that a proper solution could be to make EmitConstantValueOnly() return its constant value and call it for each argument of the GEP which will then be passed to getIndexedOffset().

I don't think that's necessary. You should be able to emit the '((', EmitConstantValueOnly(innerConstant), then emit ') * ' followed by TD->getIndexedOffset(innerConstant). Something like that, substitute whatever pattern you need.

Does this sound like a reasonable solution?

I'm concerned about the case where the parameter to the GEP really is something that can't be folded down to an integer. A GEP can be written out in terms of addition and multiplies, even if you don't know what each field is.

So as long as:

   i32 ptrtoint (i32* getelementptr (i32* @global, i32 sub (ptrtoint (i32* @symb1 to i32), (ptrtoint (i32* @symb2 to i32)))))

really does become:

  .global + ((.symb1 - .symb2) * 4)

then I'd be happy. Or if I got the example wrong, whatever the right answer really is :wink:

Nick