diff mbox

[6/n] OpenMP 4.0 offloading infrastructure: option handling

Message ID 87lhjue1lz.fsf@schwinge.name
State New
Headers show

Commit Message

Thomas Schwinge Feb. 19, 2015, 8:39 a.m. UTC
Hi!

On Wed, 18 Feb 2015 18:04:21 +0100, I wrote:
> On Mon, 13 Oct 2014 14:33:11 +0400, Ilya Verbin <iverbin@gmail.com> wrote:
> > On 13 Oct 12:19, Jakub Jelinek wrote:
> > > On Sat, Oct 11, 2014 at 06:49:00PM +0400, Ilya Verbin wrote:
> > > > 2. -foffload-abi=[lp64|ilp32]
> > > >    This option is supposed to tell mkoffload (and offload compiler) which ABI is
> > > > used in streamed GIMPLE.  This option is desirable, because host and offload
> > > > compilers must have the same ABI.  The option is generated by the host compiler
> > > > automatically, it should not be specified by user.
> > > 
> > > But I'd like to understand why is this one needed.
> > > Why should the compilers care?  Aggregates layout and alignment of
> > > integral/floating types must match between host and offload compilers, sure,
> > > but isn't that something streamed already in the LTO bytecode?
> > > Or is LTO streamer not streaming some types like long_type_node?
> > > I'd expect if host and offload compiler disagree on long type size that
> > > you'd just use a different integral type with the same size as long on the
> > > host.
> > > Different sized pointers are of course a bigger problem, but can't you just
> > > error out on that during reading of the LTO, or even handle it (just use
> > > some integral type for when is the pointer stored in memory, and just
> > > convert to pointer after reads from memory, and convert back before storing
> > > to memory).  Erroring out during LTO streaming in sounds just fine to me
> > > though.
> > 
> > Actually this option was developed by Bernd, so I think PTX team is going to use
> > it somehow.  In MIC's case we're planning just to check in mkoffload that host
> > and target compiler's ABI are the same.  Without this check we will crash in LTO
> > streamer with ICE, so I'd like to issue an error message, rather than crashing.
> 
> In gcc/config/i386/intelmic-mkoffload.c, this option is now parsed to
> initialize the target_ilp32 variable, which will then be used
> (target_ilp32 ? "-m32" : "-m64") when invoking different tools.
> 
> In nvptx, we've been using the following approach:
> 
> --- gcc/config/nvptx/nvptx.h
> +++ gcc/config/nvptx/nvptx.h
> @@ -54,24 +54,28 @@
>  
>  /* Type Layout.  */
>  
> +#define TARGET_64BIT \
> +  (flag_offload_abi == OFFLOAD_ABI_UNSET ? TARGET_ABI64 \
> +   : flag_offload_abi == OFFLOAD_ABI_LP64 ? true : false)
> +
>  #define DEFAULT_SIGNED_CHAR 1
>  
>  #define SHORT_TYPE_SIZE 16
>  #define INT_TYPE_SIZE 32
> -#define LONG_TYPE_SIZE (TARGET_ABI64 ? 64 : 32)
> +#define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
>  #define LONG_LONG_TYPE_SIZE 64
>  #define FLOAT_TYPE_SIZE 32
>  #define DOUBLE_TYPE_SIZE 64
>  #define LONG_DOUBLE_TYPE_SIZE 64
>  
>  #undef SIZE_TYPE
> -#define SIZE_TYPE (TARGET_ABI64 ? "long unsigned int" : "unsigned int")
> +#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
>  #undef PTRDIFF_TYPE
> -#define PTRDIFF_TYPE (TARGET_ABI64 ? "long int" : "int")
> +#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
>  
> -#define POINTER_SIZE (TARGET_ABI64 ? 64 : 32)
> +#define POINTER_SIZE (TARGET_64BIT ? 64 : 32)
>  
> -#define Pmode (TARGET_ABI64 ? DImode : SImode)
> +#define Pmode (TARGET_64BIT ? DImode : SImode)
>  
>  /* Registers.  Since ptx is a virtual target, we just define a few
>     hard registers for special purposes and leave pseudos unallocated.  */
> 
> Should we settle on one of the two, that is, either pass -m[...] from
> mkoffload, or handle flag_offload_abi in the respective backend?  I think
> I prefer the intelmic-mkoffload.c approach; this seems cleaner to me:
> mkoffload "configures" the offloading compiler.  (Also, the flag 32-bit
> vs. 64-bit flag may in fact be needed for tools other than the offloading
> compiler).

Well, "for instance", when in -m32 mode, we also need to use it in
gcc/config/nvptx/mkoffload.c:compile_native -- otherwise, later on, the
linker will not be happy with the request to link a 64-bit object file
with 32-bit object files...

> Bernd, is there any specific reason for the approach you had
> chosen?

OK to do the following instead?  (Coding style/code copied from
gcc/config/i386/intelmic-mkoffload.c for consistency.)



Grüße,
 Thomas

Comments

Thomas Schwinge March 10, 2015, 12:37 p.m. UTC | #1
Hi!

Ping.

On Thu, 19 Feb 2015 09:39:52 +0100, I wrote:
> On Wed, 18 Feb 2015 18:04:21 +0100, I wrote:
> > On Mon, 13 Oct 2014 14:33:11 +0400, Ilya Verbin <iverbin@gmail.com> wrote:
> > > On 13 Oct 12:19, Jakub Jelinek wrote:
> > > > On Sat, Oct 11, 2014 at 06:49:00PM +0400, Ilya Verbin wrote:
> > > > > 2. -foffload-abi=[lp64|ilp32]
> > > > >    This option is supposed to tell mkoffload (and offload compiler) which ABI is
> > > > > used in streamed GIMPLE.  This option is desirable, because host and offload
> > > > > compilers must have the same ABI.  The option is generated by the host compiler
> > > > > automatically, it should not be specified by user.
> > > > 
> > > > But I'd like to understand why is this one needed.
> > > > Why should the compilers care?  Aggregates layout and alignment of
> > > > integral/floating types must match between host and offload compilers, sure,
> > > > but isn't that something streamed already in the LTO bytecode?
> > > > Or is LTO streamer not streaming some types like long_type_node?
> > > > I'd expect if host and offload compiler disagree on long type size that
> > > > you'd just use a different integral type with the same size as long on the
> > > > host.
> > > > Different sized pointers are of course a bigger problem, but can't you just
> > > > error out on that during reading of the LTO, or even handle it (just use
> > > > some integral type for when is the pointer stored in memory, and just
> > > > convert to pointer after reads from memory, and convert back before storing
> > > > to memory).  Erroring out during LTO streaming in sounds just fine to me
> > > > though.
> > > 
> > > Actually this option was developed by Bernd, so I think PTX team is going to use
> > > it somehow.  In MIC's case we're planning just to check in mkoffload that host
> > > and target compiler's ABI are the same.  Without this check we will crash in LTO
> > > streamer with ICE, so I'd like to issue an error message, rather than crashing.
> > 
> > In gcc/config/i386/intelmic-mkoffload.c, this option is now parsed to
> > initialize the target_ilp32 variable, which will then be used
> > (target_ilp32 ? "-m32" : "-m64") when invoking different tools.
> > 
> > In nvptx, we've been using the following approach:
> > 
> > --- gcc/config/nvptx/nvptx.h
> > +++ gcc/config/nvptx/nvptx.h
> > @@ -54,24 +54,28 @@
> >  
> >  /* Type Layout.  */
> >  
> > +#define TARGET_64BIT \
> > +  (flag_offload_abi == OFFLOAD_ABI_UNSET ? TARGET_ABI64 \
> > +   : flag_offload_abi == OFFLOAD_ABI_LP64 ? true : false)
> > +
> >  #define DEFAULT_SIGNED_CHAR 1
> >  
> >  #define SHORT_TYPE_SIZE 16
> >  #define INT_TYPE_SIZE 32
> > -#define LONG_TYPE_SIZE (TARGET_ABI64 ? 64 : 32)
> > +#define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
> >  #define LONG_LONG_TYPE_SIZE 64
> >  #define FLOAT_TYPE_SIZE 32
> >  #define DOUBLE_TYPE_SIZE 64
> >  #define LONG_DOUBLE_TYPE_SIZE 64
> >  
> >  #undef SIZE_TYPE
> > -#define SIZE_TYPE (TARGET_ABI64 ? "long unsigned int" : "unsigned int")
> > +#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
> >  #undef PTRDIFF_TYPE
> > -#define PTRDIFF_TYPE (TARGET_ABI64 ? "long int" : "int")
> > +#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
> >  
> > -#define POINTER_SIZE (TARGET_ABI64 ? 64 : 32)
> > +#define POINTER_SIZE (TARGET_64BIT ? 64 : 32)
> >  
> > -#define Pmode (TARGET_ABI64 ? DImode : SImode)
> > +#define Pmode (TARGET_64BIT ? DImode : SImode)
> >  
> >  /* Registers.  Since ptx is a virtual target, we just define a few
> >     hard registers for special purposes and leave pseudos unallocated.  */
> > 
> > Should we settle on one of the two, that is, either pass -m[...] from
> > mkoffload, or handle flag_offload_abi in the respective backend?  I think
> > I prefer the intelmic-mkoffload.c approach; this seems cleaner to me:
> > mkoffload "configures" the offloading compiler.  (Also, the flag 32-bit
> > vs. 64-bit flag may in fact be needed for tools other than the offloading
> > compiler).
> 
> Well, "for instance", when in -m32 mode, we also need to use it in
> gcc/config/nvptx/mkoffload.c:compile_native -- otherwise, later on, the
> linker will not be happy with the request to link a 64-bit object file
> with 32-bit object files...
> 
> > Bernd, is there any specific reason for the approach you had
> > chosen?
> 
> OK to do the following instead?  (Coding style/code copied from
> gcc/config/i386/intelmic-mkoffload.c for consistency.)
> 
> --- gcc/config/nvptx/mkoffload.c
> +++ gcc/config/nvptx/mkoffload.c
> @@ -126,6 +126,9 @@ static id_map *var_ids, **vars_tail = &var_ids;
>  static const char *ptx_name;
>  static const char *ptx_cfile_name;
>  
> +/* Shows if we should compile binaries for i386 instead of x86-64.  */
> +bool target_ilp32 = false;
> +
>  /* Delete tempfiles.  */
>  
>  /* Unlink a temporary file unless requested otherwise.  */
> @@ -883,6 +886,7 @@ compile_native (const char *infile, const char *outfile, const char *compiler)
>    struct obstack argv_obstack;
>    obstack_init (&argv_obstack);
>    obstack_ptr_grow (&argv_obstack, compiler);
> +  obstack_ptr_grow (&argv_obstack, target_ilp32 ? "-m32" : "-m64");
>    obstack_ptr_grow (&argv_obstack, infile);
>    obstack_ptr_grow (&argv_obstack, "-c");
>    obstack_ptr_grow (&argv_obstack, "-o");
> @@ -960,10 +964,23 @@ main (int argc, char **argv)
>       passed with @file.  Expand them into argv before processing.  */
>    expandargv (&argc, &argv);
>  
> +  /* Find out whether we should compile binaries for i386 or x86-64.  */
> +  for (int i = argc - 1; i > 0; i--)
> +    if (strncmp (argv[i], "-foffload-abi=", sizeof ("-foffload-abi=") - 1) == 0)
> +      {
> +	if (strstr (argv[i], "ilp32"))
> +	  target_ilp32 = true;
> +	else if (!strstr (argv[i], "lp64"))
> +	  fatal_error (input_location,
> +		       "unrecognizable argument of option -foffload-abi");
> +	break;
> +      }
> +
>    struct obstack argv_obstack;
>    obstack_init (&argv_obstack);
>    obstack_ptr_grow (&argv_obstack, driver);
>    obstack_ptr_grow (&argv_obstack, "-xlto");
> +  obstack_ptr_grow (&argv_obstack, target_ilp32 ? "-m32" : "-m64");
>    obstack_ptr_grow (&argv_obstack, "-S");
>  
>    for (int ix = 1; ix != argc; ix++)
> diff --git gcc/config/nvptx/nvptx.h gcc/config/nvptx/nvptx.h
> index 15460b7..e74d16f 100644
> --- gcc/config/nvptx/nvptx.h
> +++ gcc/config/nvptx/nvptx.h
> @@ -58,28 +58,24 @@
>  
>  /* Type Layout.  */
>  
> -#define TARGET_64BIT \
> -  (flag_offload_abi == OFFLOAD_ABI_UNSET ? TARGET_ABI64 \
> -   : flag_offload_abi == OFFLOAD_ABI_LP64 ? true : false)
> -
>  #define DEFAULT_SIGNED_CHAR 1
>  
>  #define SHORT_TYPE_SIZE 16
>  #define INT_TYPE_SIZE 32
> -#define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
> +#define LONG_TYPE_SIZE (TARGET_ABI64 ? 64 : 32)
>  #define LONG_LONG_TYPE_SIZE 64
>  #define FLOAT_TYPE_SIZE 32
>  #define DOUBLE_TYPE_SIZE 64
>  #define LONG_DOUBLE_TYPE_SIZE 64
>  
>  #undef SIZE_TYPE
> -#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
> +#define SIZE_TYPE (TARGET_ABI64 ? "long unsigned int" : "unsigned int")
>  #undef PTRDIFF_TYPE
> -#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
> +#define PTRDIFF_TYPE (TARGET_ABI64 ? "long int" : "int")
>  
> -#define POINTER_SIZE (TARGET_64BIT ? 64 : 32)
> +#define POINTER_SIZE (TARGET_ABI64 ? 64 : 32)
>  
> -#define Pmode (TARGET_64BIT ? DImode : SImode)
> +#define Pmode (TARGET_ABI64 ? DImode : SImode)
>  
>  /* Registers.  Since ptx is a virtual target, we just define a few
>     hard registers for special purposes and leave pseudos unallocated.  */


Grüße,
 Thomas
Thomas Schwinge April 27, 2015, 4:08 p.m. UTC | #2
Hi!

Ping.

On Tue, 10 Mar 2015 13:37:47 +0100, I wrote:
> Ping.
> 
> On Thu, 19 Feb 2015 09:39:52 +0100, I wrote:
> > On Wed, 18 Feb 2015 18:04:21 +0100, I wrote:
> > > On Mon, 13 Oct 2014 14:33:11 +0400, Ilya Verbin <iverbin@gmail.com> wrote:
> > > > On 13 Oct 12:19, Jakub Jelinek wrote:
> > > > > On Sat, Oct 11, 2014 at 06:49:00PM +0400, Ilya Verbin wrote:
> > > > > > 2. -foffload-abi=[lp64|ilp32]
> > > > > >    This option is supposed to tell mkoffload (and offload compiler) which ABI is
> > > > > > used in streamed GIMPLE.  This option is desirable, because host and offload
> > > > > > compilers must have the same ABI.  The option is generated by the host compiler
> > > > > > automatically, it should not be specified by user.
> > > > > 
> > > > > But I'd like to understand why is this one needed.
> > > > > Why should the compilers care?  Aggregates layout and alignment of
> > > > > integral/floating types must match between host and offload compilers, sure,
> > > > > but isn't that something streamed already in the LTO bytecode?
> > > > > Or is LTO streamer not streaming some types like long_type_node?
> > > > > I'd expect if host and offload compiler disagree on long type size that
> > > > > you'd just use a different integral type with the same size as long on the
> > > > > host.
> > > > > Different sized pointers are of course a bigger problem, but can't you just
> > > > > error out on that during reading of the LTO, or even handle it (just use
> > > > > some integral type for when is the pointer stored in memory, and just
> > > > > convert to pointer after reads from memory, and convert back before storing
> > > > > to memory).  Erroring out during LTO streaming in sounds just fine to me
> > > > > though.
> > > > 
> > > > Actually this option was developed by Bernd, so I think PTX team is going to use
> > > > it somehow.  In MIC's case we're planning just to check in mkoffload that host
> > > > and target compiler's ABI are the same.  Without this check we will crash in LTO
> > > > streamer with ICE, so I'd like to issue an error message, rather than crashing.
> > > 
> > > In gcc/config/i386/intelmic-mkoffload.c, this option is now parsed to
> > > initialize the target_ilp32 variable, which will then be used
> > > (target_ilp32 ? "-m32" : "-m64") when invoking different tools.
> > > 
> > > In nvptx, we've been using the following approach:
> > > 
> > > --- gcc/config/nvptx/nvptx.h
> > > +++ gcc/config/nvptx/nvptx.h
> > > @@ -54,24 +54,28 @@
> > >  
> > >  /* Type Layout.  */
> > >  
> > > +#define TARGET_64BIT \
> > > +  (flag_offload_abi == OFFLOAD_ABI_UNSET ? TARGET_ABI64 \
> > > +   : flag_offload_abi == OFFLOAD_ABI_LP64 ? true : false)
> > > +
> > >  #define DEFAULT_SIGNED_CHAR 1
> > >  
> > >  #define SHORT_TYPE_SIZE 16
> > >  #define INT_TYPE_SIZE 32
> > > -#define LONG_TYPE_SIZE (TARGET_ABI64 ? 64 : 32)
> > > +#define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
> > >  #define LONG_LONG_TYPE_SIZE 64
> > >  #define FLOAT_TYPE_SIZE 32
> > >  #define DOUBLE_TYPE_SIZE 64
> > >  #define LONG_DOUBLE_TYPE_SIZE 64
> > >  
> > >  #undef SIZE_TYPE
> > > -#define SIZE_TYPE (TARGET_ABI64 ? "long unsigned int" : "unsigned int")
> > > +#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
> > >  #undef PTRDIFF_TYPE
> > > -#define PTRDIFF_TYPE (TARGET_ABI64 ? "long int" : "int")
> > > +#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
> > >  
> > > -#define POINTER_SIZE (TARGET_ABI64 ? 64 : 32)
> > > +#define POINTER_SIZE (TARGET_64BIT ? 64 : 32)
> > >  
> > > -#define Pmode (TARGET_ABI64 ? DImode : SImode)
> > > +#define Pmode (TARGET_64BIT ? DImode : SImode)
> > >  
> > >  /* Registers.  Since ptx is a virtual target, we just define a few
> > >     hard registers for special purposes and leave pseudos unallocated.  */
> > > 
> > > Should we settle on one of the two, that is, either pass -m[...] from
> > > mkoffload, or handle flag_offload_abi in the respective backend?  I think
> > > I prefer the intelmic-mkoffload.c approach; this seems cleaner to me:
> > > mkoffload "configures" the offloading compiler.  (Also, the flag 32-bit
> > > vs. 64-bit flag may in fact be needed for tools other than the offloading
> > > compiler).
> > 
> > Well, "for instance", when in -m32 mode, we also need to use it in
> > gcc/config/nvptx/mkoffload.c:compile_native -- otherwise, later on, the
> > linker will not be happy with the request to link a 64-bit object file
> > with 32-bit object files...
> > 
> > > Bernd, is there any specific reason for the approach you had
> > > chosen?
> > 
> > OK to do the following instead?  (Coding style/code copied from
> > gcc/config/i386/intelmic-mkoffload.c for consistency.)
> > 
> > --- gcc/config/nvptx/mkoffload.c
> > +++ gcc/config/nvptx/mkoffload.c
> > @@ -126,6 +126,9 @@ static id_map *var_ids, **vars_tail = &var_ids;
> >  static const char *ptx_name;
> >  static const char *ptx_cfile_name;
> >  
> > +/* Shows if we should compile binaries for i386 instead of x86-64.  */
> > +bool target_ilp32 = false;
> > +
> >  /* Delete tempfiles.  */
> >  
> >  /* Unlink a temporary file unless requested otherwise.  */
> > @@ -883,6 +886,7 @@ compile_native (const char *infile, const char *outfile, const char *compiler)
> >    struct obstack argv_obstack;
> >    obstack_init (&argv_obstack);
> >    obstack_ptr_grow (&argv_obstack, compiler);
> > +  obstack_ptr_grow (&argv_obstack, target_ilp32 ? "-m32" : "-m64");
> >    obstack_ptr_grow (&argv_obstack, infile);
> >    obstack_ptr_grow (&argv_obstack, "-c");
> >    obstack_ptr_grow (&argv_obstack, "-o");
> > @@ -960,10 +964,23 @@ main (int argc, char **argv)
> >       passed with @file.  Expand them into argv before processing.  */
> >    expandargv (&argc, &argv);
> >  
> > +  /* Find out whether we should compile binaries for i386 or x86-64.  */
> > +  for (int i = argc - 1; i > 0; i--)
> > +    if (strncmp (argv[i], "-foffload-abi=", sizeof ("-foffload-abi=") - 1) == 0)
> > +      {
> > +	if (strstr (argv[i], "ilp32"))
> > +	  target_ilp32 = true;
> > +	else if (!strstr (argv[i], "lp64"))
> > +	  fatal_error (input_location,
> > +		       "unrecognizable argument of option -foffload-abi");
> > +	break;
> > +      }
> > +
> >    struct obstack argv_obstack;
> >    obstack_init (&argv_obstack);
> >    obstack_ptr_grow (&argv_obstack, driver);
> >    obstack_ptr_grow (&argv_obstack, "-xlto");
> > +  obstack_ptr_grow (&argv_obstack, target_ilp32 ? "-m32" : "-m64");
> >    obstack_ptr_grow (&argv_obstack, "-S");
> >  
> >    for (int ix = 1; ix != argc; ix++)
> > diff --git gcc/config/nvptx/nvptx.h gcc/config/nvptx/nvptx.h
> > index 15460b7..e74d16f 100644
> > --- gcc/config/nvptx/nvptx.h
> > +++ gcc/config/nvptx/nvptx.h
> > @@ -58,28 +58,24 @@
> >  
> >  /* Type Layout.  */
> >  
> > -#define TARGET_64BIT \
> > -  (flag_offload_abi == OFFLOAD_ABI_UNSET ? TARGET_ABI64 \
> > -   : flag_offload_abi == OFFLOAD_ABI_LP64 ? true : false)
> > -
> >  #define DEFAULT_SIGNED_CHAR 1
> >  
> >  #define SHORT_TYPE_SIZE 16
> >  #define INT_TYPE_SIZE 32
> > -#define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
> > +#define LONG_TYPE_SIZE (TARGET_ABI64 ? 64 : 32)
> >  #define LONG_LONG_TYPE_SIZE 64
> >  #define FLOAT_TYPE_SIZE 32
> >  #define DOUBLE_TYPE_SIZE 64
> >  #define LONG_DOUBLE_TYPE_SIZE 64
> >  
> >  #undef SIZE_TYPE
> > -#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
> > +#define SIZE_TYPE (TARGET_ABI64 ? "long unsigned int" : "unsigned int")
> >  #undef PTRDIFF_TYPE
> > -#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
> > +#define PTRDIFF_TYPE (TARGET_ABI64 ? "long int" : "int")
> >  
> > -#define POINTER_SIZE (TARGET_64BIT ? 64 : 32)
> > +#define POINTER_SIZE (TARGET_ABI64 ? 64 : 32)
> >  
> > -#define Pmode (TARGET_64BIT ? DImode : SImode)
> > +#define Pmode (TARGET_ABI64 ? DImode : SImode)
> >  
> >  /* Registers.  Since ptx is a virtual target, we just define a few
> >     hard registers for special purposes and leave pseudos unallocated.  */


Grüße,
 Thomas
Bernd Schmidt April 28, 2015, 1:24 p.m. UTC | #3
On 04/27/2015 06:08 PM, Thomas Schwinge wrote:

>>> OK to do the following instead?  (Coding style/code copied from
>>> gcc/config/i386/intelmic-mkoffload.c for consistency.)

Err, was this a question for me? I'm fine with that too.


Bernd
diff mbox

Patch

--- gcc/config/nvptx/mkoffload.c
+++ gcc/config/nvptx/mkoffload.c
@@ -126,6 +126,9 @@  static id_map *var_ids, **vars_tail = &var_ids;
 static const char *ptx_name;
 static const char *ptx_cfile_name;
 
+/* Shows if we should compile binaries for i386 instead of x86-64.  */
+bool target_ilp32 = false;
+
 /* Delete tempfiles.  */
 
 /* Unlink a temporary file unless requested otherwise.  */
@@ -883,6 +886,7 @@  compile_native (const char *infile, const char *outfile, const char *compiler)
   struct obstack argv_obstack;
   obstack_init (&argv_obstack);
   obstack_ptr_grow (&argv_obstack, compiler);
+  obstack_ptr_grow (&argv_obstack, target_ilp32 ? "-m32" : "-m64");
   obstack_ptr_grow (&argv_obstack, infile);
   obstack_ptr_grow (&argv_obstack, "-c");
   obstack_ptr_grow (&argv_obstack, "-o");
@@ -960,10 +964,23 @@  main (int argc, char **argv)
      passed with @file.  Expand them into argv before processing.  */
   expandargv (&argc, &argv);
 
+  /* Find out whether we should compile binaries for i386 or x86-64.  */
+  for (int i = argc - 1; i > 0; i--)
+    if (strncmp (argv[i], "-foffload-abi=", sizeof ("-foffload-abi=") - 1) == 0)
+      {
+	if (strstr (argv[i], "ilp32"))
+	  target_ilp32 = true;
+	else if (!strstr (argv[i], "lp64"))
+	  fatal_error (input_location,
+		       "unrecognizable argument of option -foffload-abi");
+	break;
+      }
+
   struct obstack argv_obstack;
   obstack_init (&argv_obstack);
   obstack_ptr_grow (&argv_obstack, driver);
   obstack_ptr_grow (&argv_obstack, "-xlto");
+  obstack_ptr_grow (&argv_obstack, target_ilp32 ? "-m32" : "-m64");
   obstack_ptr_grow (&argv_obstack, "-S");
 
   for (int ix = 1; ix != argc; ix++)
diff --git gcc/config/nvptx/nvptx.h gcc/config/nvptx/nvptx.h
index 15460b7..e74d16f 100644
--- gcc/config/nvptx/nvptx.h
+++ gcc/config/nvptx/nvptx.h
@@ -58,28 +58,24 @@ 
 
 /* Type Layout.  */
 
-#define TARGET_64BIT \
-  (flag_offload_abi == OFFLOAD_ABI_UNSET ? TARGET_ABI64 \
-   : flag_offload_abi == OFFLOAD_ABI_LP64 ? true : false)
-
 #define DEFAULT_SIGNED_CHAR 1
 
 #define SHORT_TYPE_SIZE 16
 #define INT_TYPE_SIZE 32
-#define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
+#define LONG_TYPE_SIZE (TARGET_ABI64 ? 64 : 32)
 #define LONG_LONG_TYPE_SIZE 64
 #define FLOAT_TYPE_SIZE 32
 #define DOUBLE_TYPE_SIZE 64
 #define LONG_DOUBLE_TYPE_SIZE 64
 
 #undef SIZE_TYPE
-#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
+#define SIZE_TYPE (TARGET_ABI64 ? "long unsigned int" : "unsigned int")
 #undef PTRDIFF_TYPE
-#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
+#define PTRDIFF_TYPE (TARGET_ABI64 ? "long int" : "int")
 
-#define POINTER_SIZE (TARGET_64BIT ? 64 : 32)
+#define POINTER_SIZE (TARGET_ABI64 ? 64 : 32)
 
-#define Pmode (TARGET_64BIT ? DImode : SImode)
+#define Pmode (TARGET_ABI64 ? DImode : SImode)
 
 /* Registers.  Since ptx is a virtual target, we just define a few
    hard registers for special purposes and leave pseudos unallocated.  */