hfinkel added a comment.

In http://reviews.llvm.org/D17103#349280, @jlebar wrote:

> > > I guess this is the part I'm unsure of.  If it's legal to pass a struct 
> > > to printf in regular C++ (seems to be?), I'd guess it should be legal in 
> > > CUDA, too?  I'm just not sure what it's supposed to do (in either case).
>
> > 
>
> > 
>
> > Is this because PTX does not have a way to represent va_arg structs?
>
>
> We do build up something that looks an awful lot like a va_arg struct in this 
> function.  (It's a struct with N members, one for each of the varargs.)  
> Exactly what printf expects is not particularly carefully specified in the 
> nvvm documentation.
>
> If an arg to printf is non-scalar, we could pass the whole thing into the 
> struct we build here, but that doesn't seem to be what regular C++ does (it 
> seems to take the first 64 bits of the struct -- I have no idea if this is 
> specified somewhere or just UB).


It takes the first 64 bits of the struct in your example because the struct is 
only 64 bits in size (two 32-bit ints). If you're example was:

  $ cat /tmp/p.cpp 
  #include <stdio.h>
  
  struct Struct {
    int x;
    int y;
    int z;
    int w;
  };
  
  void PrintfNonScalar() {
    Struct S = { 1, 2, 3, 4 };
    printf("%d", S);
  }

then you'd get:

  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
  target triple = "x86_64-unknown-linux-gnu"
  
  @.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1
  
  ; Function Attrs: nounwind uwtable
  define void @_Z15PrintfNonScalarv() #0 {
    %1 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], 
[3 x i8]* @.str, i64 0, i64 0), i64 8589934593, i64 17179869187)
    ret void
  }

and so on. The target ABI code decides how to handle this (by coercing the 
types to a series of ints in this case).

If you were to do this on ppc64, for example, the target ABI code there does a 
slightly different thing:

  target datalayout = "E-m:e-i64:64-n32:64"
  target triple = "powerpc64-unknown-linux-gnu"
  
  @.str = private unnamed_addr constant [3 x i8] c"%d\00", align 1
  
  ; Function Attrs: nounwind
  define void @_Z15PrintfNonScalarv() #0 {
    %1 = tail call signext i32 (i8*, ...) @printf(i8* getelementptr inbounds 
([3 x i8], [3 x i8]* @.str, i64 0, i64 0), [2 x i64] [i64 4294967298, i64 
12884901892])
    ret void
  }

it looks like maybe you just need some more sophisticated code in NVPTXABIInfo 
in lib/CodeGen/TargetInfo.cpp to produce something the backend will accept?


http://reviews.llvm.org/D17103



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to