Wrong Users count for global string in clang/test/CodeGen/2009-02-13-zerosize-union-field.c

Hi,

I’m writing some code transformations using CLang. When I run my code on clang/test/CodeGen/2009-02-13-zerosize-union-field.c :

typedef unsigned int Foo attribute((aligned(32)));
typedef union{Foo:0;}a;
typedef union{int x; Foo:0;}b;
extern int printf(const char*, …);
int main() {
// CHECK: getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i32 0, i32 0), i32 0
printf("%ld\n", sizeof(a));
// CHECK: getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i32 0, i32 0), i32 1
printf("%ld\n", alignof(a));
// CHECK: getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i32 0, i32 0), i32 4
printf("%ld\n", sizeof(b));
// CHECK: getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i32 0, i32 0), i32 4
printf("%ld\n", alignof(b));
}

I see that when I iterate the users() of the “%ld\n” string, only the last user is reported. Here’s my code for doing the iteration:

for (llvm::GlobalVariable &Glob : TheModule.globals())

for (User *U : Glob.users())
outs() << "User " << *U << “\n”;

The 4 different calls are clearly visible in the .ll file:

%call = call i32 (i8*, …) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"??_C@_04PEDNGLFL@?$CFld?6?$AA@", i64 0, i64 0), i64 4)
%call1 = call i32 (i8*, …) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"??_C@_04PEDNGLFL@?$CFld?6?$AA@", i64 0, i64 0), i64 1)
%call2 = call i32 (i8*, …) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"??_C@_04PEDNGLFL@?$CFld?6?$AA@", i64 0, i64 0), i64 4)
%call3 = call i32 (i8*, …) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"??_C@_04PEDNGLFL@?$CFld?6?$AA@", i64 0, i64 0), i64 4)

Any idea why this is happening?

Thanks

Each call appears to use an identical ConstantExpr getelementptr. Each of those ConstantExprs is represented by the same object in the memory representation of IR even though its printed in 4 separate places. If you walk the users of that object you should find the 4 calls.

I see, thanks!

I actually was iterating over the users of the GEP in another place but my mistake was altering the containing function while iterating, which ended the iteration mid way.

Cheers,