ValueMapper question: no type mapping for GlobalValue?

Hi all, I was looking at the ValueMapper code this morning and I notice that
it doesn't do type mapping for GlobalValues. Is this correct?

I ask because I am seeing a case where I'm failing type assertions from
ModuleLinker::linkGlobalInits() when an array initializer references an
external global. It looks like the external global is being mapped directly
and this causes an element type check to fail in ConstantArray::get().
Curiously, this only happens when that external global is also referenced from
within a function in the same module.

Do you have a testcase?

I tried to reproduce this with

=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?= wrote:

>
> Hi all, I was looking at the ValueMapper code this morning and I notice that
> it doesn't do type mapping for GlobalValues. Is this correct?
>
> I ask because I am seeing a case where I'm failing type assertions from
> ModuleLinker::linkGlobalInits() when an array initializer references an
> external global. It looks like the external global is being mapped directly
> and this causes an element type check to fail in ConstantArray::get().
> Curiously, this only happens when that external global is also referenced from
> within a function in the same module.
>

Do you have a testcase?

I tried to reproduce this with

-----------
a = global i64 42, align 8
-----------

and

----------
@a = external global i32
@b = constant [1 x i32*] [i32* @a], align 8

define i32 @f() nounwind uwtable readonly optsize {
entry:
  %0 = load i32* @a, align 4
  ret i32 %0
}
----------

but llvm-link correctly produced

@b = constant [1 x i32*] [i32* bitcast (i64* @a to i32*)], align 8
@a = global i64 42, align 8

define i32 @f() nounwind uwtable readonly optsize {
entry:
  %0 = load i32* bitcast (i64* @a to i32*), align 4
  ret i32 %0
}

I can reproduce this consistently, but only under an extremely large pile of
code :slight_smile: I haven't tried to strip it down to minimal a test case yet, but I
will. One salient difference with the code you've provided is that in my
code, @a is a struct type. However, changing the example to use a minimal
structure doesn't trigger the assertion failure.

But I'm still curious: why doesn't the value mapper do type mapping on global
variables?

I can reproduce this consistently, but only under an extremely large pile of
code :slight_smile: I haven't tried to strip it down to minimal a test case yet, but I
will. One salient difference with the code you've provided is that in my
code, @a is a struct type. However, changing the example to use a minimal
structure doesn't trigger the assertion failure.

Is the example something you can share even in unreduced for?

But I'm still curious: why doesn't the value mapper do type mapping on global
variables?

I am not sure. I would probably have to look at a failing example to
know what is going on.

Cheers,
Rafael

=?ISO-8859-1?Q?Rafael_=C1vila_de_Esp=EDndola?= wrote:

> I can reproduce this consistently, but only under an extremely large pile of
> code :slight_smile: I haven't tried to strip it down to minimal a test case yet, but I
> will. One salient difference with the code you've provided is that in my
> code, @a is a struct type. However, changing the example to use a minimal
> structure doesn't trigger the assertion failure.

Is the example something you can share even in unreduced for?

As it turns out, the root cause was that I had a GlobalVariable that wasn't
being copied to an extern in the new module under some circumstances, but was
being used directly. I would have expected the verifier pass to catch this,
but it looks like we're probably not using the verifier except when running
non-optimized + debug, which I never tried.

I'll recreate this situation just to verify that the verifier pass identifies
the problem, if it doesn't I'll proceed from there but I'm currently assuming
the problem is entirely ours :slight_smile:

If you think the behavior of the ValueMapper is incorrect in this situation,
I'd prefer to furnish you with a minimal test case - the unreduced form
involves checking out and building a specific revision of the Crack compiler
and running one of the tests in "native" (AOT compile) mode.

Thank you for looking into this :slight_smile:

So it looks like the verifier doesn't catch this condition - I think it
should. The attached program reproduces the problem - verification succeeds,
but the linker fails with a type assertion.

BTW, if no one has the bandwidth to work on this I'm willing to attempt a fix,
assuming that you agree that the verifier should discover this condition.

Michael Muller wrote:

ReferencingExternalGlobal.cc (2 KB)

Hi Michael, did anything ever happen with this?

Ciao, Duncan.

Duncan Sands wrote:

Hi Michael, did anything ever happen with this?

No. I never got a reply from anyone so I didn't attempt a fix.

I can resume work on it. Do I have agreement that the verifier should check
for this?