Message ID | 20190106013802.3645-1-eblake@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] osdep: Make MIN/MAX evaluate arguments only once | expand |
On 1/6/19 11:38 AM, Eric Blake wrote: > +/* > + * Automatic type deduction, to be used as: > + * QEMU_TYPEOF(expr) name = expr; > + */ > +#if QEMU_GNUC_PREREQ(4, 9) > +# define QEMU_TYPEOF(a) __auto_type > +#else > +# define QEMU_TYPEOF(a) typeof(a) > +#endif What's wrong with always using typeof? This seems like it leaves potential odd bugs affecting gcc-4.8. > +#undef MIN > +#define MIN(a, b) \ > + ({ \ > + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ If you're promoting the type, why don't you want to promote to the common type between A and B? E.g. __typeof((a) + (b)) _a = (a), _b = (b); After all, that's what the result type of (p ? _a : _b) will be. r~
* Eric Blake (eblake@redhat.com) wrote: > Add the macro QEMU_TYPEOF() to access __auto_type in new enough > compilers, while falling back to typeof on older compilers (the > fallback doesn't handle variable length arrays, but we don't use > those; it also expands to more text). > > Then use that macro to make MIN/MAX only evaluate their argument > once; this uses type promotion (by adding to 0) to work around > the fact that typeof(bitfield) won't compile. However, we are > unable to work around gcc refusing to compile ({}) in a constant > context, even when only used in the dead branch of a > __builtin_choose_expr(), so we have to provide a second macro > pair MIN_CONST and MAX_CONST for use when both arguments are > known to be compile-time constants and where the result must > also be usable in constant contexts. > > Fix the resulting callsites that compute a compile-time constant > min or max to use the new macros. > > Signed-off-by: Eric Blake <eblake@redhat.com> > > --- > v2: Force use of our smart macros, and make macro handle bitfields, > constant expressions, and older compilers [Zoltan] > --- > hw/usb/hcd-xhci.h | 2 +- > include/exec/cpu-defs.h | 2 +- > include/qemu/compiler.h | 10 +++++++++ > include/qemu/osdep.h | 46 ++++++++++++++++++++++++++++++++++------- > migration/qemu-file.c | 2 +- > 5 files changed, 51 insertions(+), 11 deletions(-) > > diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h > index fc36a4c787c..10beee9a7b1 100644 > --- a/hw/usb/hcd-xhci.h > +++ b/hw/usb/hcd-xhci.h > @@ -210,7 +210,7 @@ struct XHCIState { > uint32_t dcbaap_high; > uint32_t config; > > - USBPort uports[MAX(MAXPORTS_2, MAXPORTS_3)]; > + USBPort uports[MAX_CONST(MAXPORTS_2, MAXPORTS_3)]; > XHCIPort ports[MAXPORTS]; > XHCISlot slots[MAXSLOTS]; > uint32_t numports; > diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h > index 6a60f94a41d..5b2fd46f687 100644 > --- a/include/exec/cpu-defs.h > +++ b/include/exec/cpu-defs.h > @@ -90,7 +90,7 @@ typedef uint64_t target_ulong; > * of tlb_table inside env (which is non-trivial but not huge). > */ > #define CPU_TLB_BITS \ > - MIN(8, \ > + MIN_CONST(8, \ > TCG_TARGET_TLB_DISPLACEMENT_BITS - CPU_TLB_ENTRY_BITS - \ > (NB_MMU_MODES <= 1 ? 0 : \ > NB_MMU_MODES <= 2 ? 1 : \ > diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h > index 261842beae2..3bf6f68a6b0 100644 > --- a/include/qemu/compiler.h > +++ b/include/qemu/compiler.h > @@ -191,4 +191,14 @@ > #define QEMU_GENERIC9(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC8(x, __VA_ARGS__)) > #define QEMU_GENERIC10(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC9(x, __VA_ARGS__)) > > +/* > + * Automatic type deduction, to be used as: > + * QEMU_TYPEOF(expr) name = expr; > + */ > +#if QEMU_GNUC_PREREQ(4, 9) > +# define QEMU_TYPEOF(a) __auto_type > +#else > +# define QEMU_TYPEOF(a) typeof(a) > +#endif > + > #endif /* COMPILER_H */ > diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h > index 3bf48bcdec0..821ce627f73 100644 > --- a/include/qemu/osdep.h > +++ b/include/qemu/osdep.h > @@ -232,18 +232,48 @@ extern int daemon(int, int); > #define SIZE_MAX ((size_t)-1) > #endif > > -#ifndef MIN > -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) > -#endif > -#ifndef MAX > -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) > -#endif > +/* > + * Two variations of MIN/MAX macros. The first is for runtime use, and > + * evaluates arguments only once (so it is safe even with side > + * effects), but will not work in constant contexts (such as array > + * size declarations). The second is for compile-time use, where > + * evaluating arguments twice is safe because the result is going to > + * be constant anyway. > + */ > +#undef MIN > +#define MIN(a, b) \ > + ({ \ > + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > + _a < _b ? _a : _b; \ > + }) > +#define MIN_CONST(a, b) \ > + __builtin_choose_expr( \ > + __builtin_constant_p(a) && __builtin_constant_p(b), \ > + (a) < (b) ? (a) : (b), \ > + __builtin_unreachable()) Why do these need to be separate macros? Can't you just put the non-constant code in what you have as the 'builtin_unreachable' side of the choose_expr: #define DMIN(a,b) __builtin_choose_expr( \ __builtin_constant_p(a) && __builtin_constant_p(b), \ (a) < (b) ? (a) : (b), \ ({ \ QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ _a < _b ? _a : _b; \ })) Dave > +#undef MAX > +#define MAX(a, b) \ > + ({ \ > + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > + _a > _b ? _a : _b; \ > + }) > +#define MAX_CONST(a, b) \ > + __builtin_choose_expr( \ > + __builtin_constant_p(a) && __builtin_constant_p(b), \ > + (a) > (b) ? (a) : (b), \ > + __builtin_unreachable()) > > /* Minimum function that returns zero only iff both values are zero. > * Intended for use with unsigned values only. */ > #ifndef MIN_NON_ZERO > -#define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \ > - ((b) == 0 ? (a) : (MIN(a, b)))) > +#define MIN_NON_ZERO(a, b) \ > + ({ \ > + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > + _a == 0 ? _b : (_b == 0 || _b > _a) ? _a : _b; \ > + }) > #endif > > /* Round number down to multiple */ > diff --git a/migration/qemu-file.c b/migration/qemu-file.c > index 977b9ae07c1..9746cbec0f3 100644 > --- a/migration/qemu-file.c > +++ b/migration/qemu-file.c > @@ -31,7 +31,7 @@ > #include "trace.h" > > #define IO_BUF_SIZE 32768 > -#define MAX_IOV_SIZE MIN(IOV_MAX, 64) > +#define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 64) > > struct QEMUFile { > const QEMUFileOps *ops; > -- > 2.20.1 > -- Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
On 1/6/19 2:32 AM, Richard Henderson wrote: > On 1/6/19 11:38 AM, Eric Blake wrote: >> +/* >> + * Automatic type deduction, to be used as: >> + * QEMU_TYPEOF(expr) name = expr; >> + */ >> +#if QEMU_GNUC_PREREQ(4, 9) >> +# define QEMU_TYPEOF(a) __auto_type >> +#else >> +# define QEMU_TYPEOF(a) typeof(a) >> +#endif > > What's wrong with always using typeof? This seems like it leaves potential odd > bugs affecting gcc-4.8. Always using typeof is an option, but gcc documents that __auto_type is nicer than typeof: > Using '__auto_type' instead of 'typeof' has two advantages: > > * Each argument to the macro appears only once in the expansion of > the macro. This prevents the size of the macro expansion growing > exponentially when calls to such macros are nested inside arguments > of such macros. > > * If the argument to the macro has variably modified type, it is > evaluated only once when using '__auto_type', but twice if 'typeof' > is used. We don't use variably modified types (at least, I don't think we do), so the latter is moot (but WOULD be the spot where we are most likely to be bitten on 4.8 compilers lacking __auto_type); the former point is a minor speed win in favor of __auto_type. > >> +#undef MIN >> +#define MIN(a, b) \ >> + ({ \ >> + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ >> + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > > If you're promoting the type, why don't you want to promote to the common type > between A and B? E.g. > > __typeof((a) + (b)) _a = (a), _b = (b); > > After all, that's what the result type of (p ? _a : _b) will be. That formulation should work as well, if anyone likes it better (but it does NOT work with __auto_type).
On 1/7/19 3:49 AM, Dr. David Alan Gilbert wrote: > * Eric Blake (eblake@redhat.com) wrote: >> Add the macro QEMU_TYPEOF() to access __auto_type in new enough >> compilers, while falling back to typeof on older compilers (the >> fallback doesn't handle variable length arrays, but we don't use >> those; it also expands to more text). >> >> Then use that macro to make MIN/MAX only evaluate their argument >> once; this uses type promotion (by adding to 0) to work around >> the fact that typeof(bitfield) won't compile. However, we are >> unable to work around gcc refusing to compile ({}) in a constant >> context, even when only used in the dead branch of a >> __builtin_choose_expr(), >> +#undef MIN >> +#define MIN(a, b) \ >> + ({ \ >> + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ >> + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ >> + _a < _b ? _a : _b; \ >> + }) >> +#define MIN_CONST(a, b) \ >> + __builtin_choose_expr( \ >> + __builtin_constant_p(a) && __builtin_constant_p(b), \ >> + (a) < (b) ? (a) : (b), \ >> + __builtin_unreachable()) > > Why do these need to be separate macros? Can't you just put the > non-constant code in what you have as the 'builtin_unreachable' side of > the choose_expr: > > #define DMIN(a,b) __builtin_choose_expr( \ > __builtin_constant_p(a) && __builtin_constant_p(b), \ > (a) < (b) ? (a) : (b), \ > ({ \ > QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > _a < _b ? _a : _b; \ > })) Because it doesn't work - gcc treats ({}) as a syntax error inside constant expressions, even in dead code (although 'info gcc' said that might change in the future, we can't wait for that change). I also tried it as documented here: https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg00715.html hence my mention in the commit message.
* Eric Blake (eblake@redhat.com) wrote: > On 1/7/19 3:49 AM, Dr. David Alan Gilbert wrote: > > * Eric Blake (eblake@redhat.com) wrote: > >> Add the macro QEMU_TYPEOF() to access __auto_type in new enough > >> compilers, while falling back to typeof on older compilers (the > >> fallback doesn't handle variable length arrays, but we don't use > >> those; it also expands to more text). > >> > >> Then use that macro to make MIN/MAX only evaluate their argument > >> once; this uses type promotion (by adding to 0) to work around > >> the fact that typeof(bitfield) won't compile. However, we are > >> unable to work around gcc refusing to compile ({}) in a constant > >> context, even when only used in the dead branch of a > >> __builtin_choose_expr(), > > > >> +#undef MIN > >> +#define MIN(a, b) \ > >> + ({ \ > >> + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > >> + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > >> + _a < _b ? _a : _b; \ > >> + }) > >> +#define MIN_CONST(a, b) \ > >> + __builtin_choose_expr( \ > >> + __builtin_constant_p(a) && __builtin_constant_p(b), \ > >> + (a) < (b) ? (a) : (b), \ > >> + __builtin_unreachable()) > > > > Why do these need to be separate macros? Can't you just put the > > non-constant code in what you have as the 'builtin_unreachable' side of > > the choose_expr: > > > > #define DMIN(a,b) __builtin_choose_expr( \ > > __builtin_constant_p(a) && __builtin_constant_p(b), \ > > (a) < (b) ? (a) : (b), \ > > ({ \ > > QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > > QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > > _a < _b ? _a : _b; \ > > })) > > Because it doesn't work - gcc treats ({}) as a syntax error inside > constant expressions, even in dead code (although 'info gcc' said that > might change in the future, we can't wait for that change). I also > tried it as documented here: > https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg00715.html > hence my mention in the commit message. Ah, I didn't understand the context in your message; you say 'even in the dead branch of a __builtin_choose_expr()' but the following works for me (on f29 and rhel7): #include <stdio.h> # define QEMU_TYPEOF(a) typeof(a) #define DMIN(a,b) __builtin_choose_expr( \ __builtin_constant_p(a) && __builtin_constant_p(b), \ (a) < (b) ? (a) : (b), \ ({ \ QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ _a < _b ? _a : _b; \ })) int main(int argc, char *argv[]) { int anarray[DMIN(5, 10)]; int a=5; int b=6; fprintf(stderr, "sizeof(anarray)=%zd DMIN(a,b)=%d\n", sizeof(anarray), DMIN(a++,b++)); fprintf(stderr, "a=%d b=%d\n", a,b); } Dave > -- > Eric Blake, Principal Software Engineer > Red Hat, Inc. +1-919-301-3226 > Virtualization: qemu.org | libvirt.org > -- Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
On 1/7/19 9:07 AM, Dr. David Alan Gilbert wrote: >>>> Then use that macro to make MIN/MAX only evaluate their argument >>>> once; this uses type promotion (by adding to 0) to work around >>>> the fact that typeof(bitfield) won't compile. However, we are >>>> unable to work around gcc refusing to compile ({}) in a constant >>>> context, even when only used in the dead branch of a >>>> __builtin_choose_expr(), >> Because it doesn't work - gcc treats ({}) as a syntax error inside >> constant expressions, even in dead code (although 'info gcc' said that >> might change in the future, we can't wait for that change). I also >> tried it as documented here: >> https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg00715.html >> hence my mention in the commit message. > > Ah, I didn't understand the context in your message; you say 'even in > the dead branch of a __builtin_choose_expr()' but the following works > for me (on f29 and rhel7): > > #include <stdio.h> > > # define QEMU_TYPEOF(a) typeof(a) > > #define DMIN(a,b) __builtin_choose_expr( \ > __builtin_constant_p(a) && __builtin_constant_p(b), \ > (a) < (b) ? (a) : (b), \ > ({ \ > QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > _a < _b ? _a : _b; \ > })) > > > int main(int argc, char *argv[]) > { > int anarray[DMIN(5, 10)]; Not a constant context. As written, you have declared a variable-length array, determined at runtime (even if the array is not actually variable-length because you always provide the same length). Hoist the declaration anarray outside of main() to see the difference. Or try: struct foo { int bar : DMIN(5, 10); }; for another example of a constant context (again, outside of a function).
* Eric Blake (eblake@redhat.com) wrote: > On 1/7/19 9:07 AM, Dr. David Alan Gilbert wrote: > > >>>> Then use that macro to make MIN/MAX only evaluate their argument > >>>> once; this uses type promotion (by adding to 0) to work around > >>>> the fact that typeof(bitfield) won't compile. However, we are > >>>> unable to work around gcc refusing to compile ({}) in a constant > >>>> context, even when only used in the dead branch of a > >>>> __builtin_choose_expr(), > > >> Because it doesn't work - gcc treats ({}) as a syntax error inside > >> constant expressions, even in dead code (although 'info gcc' said that > >> might change in the future, we can't wait for that change). I also > >> tried it as documented here: > >> https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg00715.html > >> hence my mention in the commit message. > > > > Ah, I didn't understand the context in your message; you say 'even in > > the dead branch of a __builtin_choose_expr()' but the following works > > for me (on f29 and rhel7): > > > > #include <stdio.h> > > > > # define QEMU_TYPEOF(a) typeof(a) > > > > #define DMIN(a,b) __builtin_choose_expr( \ > > __builtin_constant_p(a) && __builtin_constant_p(b), \ > > (a) < (b) ? (a) : (b), \ > > ({ \ > > QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ > > QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ > > _a < _b ? _a : _b; \ > > })) > > > > > > int main(int argc, char *argv[]) > > { > > int anarray[DMIN(5, 10)]; > > Not a constant context. As written, you have declared a variable-length > array, determined at runtime (even if the array is not actually > variable-length because you always provide the same length). Hoist the > declaration anarray outside of main() to see the difference. Or try: > > struct foo { > int bar : DMIN(5, 10); > }; > > for another example of a constant context (again, outside of a function). Ah OK, yes that does fail as you say. Fair enough. Dave > -- > Eric Blake, Principal Software Engineer > Red Hat, Inc. +1-919-301-3226 > Virtualization: qemu.org | libvirt.org > -- Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h index fc36a4c787c..10beee9a7b1 100644 --- a/hw/usb/hcd-xhci.h +++ b/hw/usb/hcd-xhci.h @@ -210,7 +210,7 @@ struct XHCIState { uint32_t dcbaap_high; uint32_t config; - USBPort uports[MAX(MAXPORTS_2, MAXPORTS_3)]; + USBPort uports[MAX_CONST(MAXPORTS_2, MAXPORTS_3)]; XHCIPort ports[MAXPORTS]; XHCISlot slots[MAXSLOTS]; uint32_t numports; diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 6a60f94a41d..5b2fd46f687 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -90,7 +90,7 @@ typedef uint64_t target_ulong; * of tlb_table inside env (which is non-trivial but not huge). */ #define CPU_TLB_BITS \ - MIN(8, \ + MIN_CONST(8, \ TCG_TARGET_TLB_DISPLACEMENT_BITS - CPU_TLB_ENTRY_BITS - \ (NB_MMU_MODES <= 1 ? 0 : \ NB_MMU_MODES <= 2 ? 1 : \ diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 261842beae2..3bf6f68a6b0 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -191,4 +191,14 @@ #define QEMU_GENERIC9(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC8(x, __VA_ARGS__)) #define QEMU_GENERIC10(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC9(x, __VA_ARGS__)) +/* + * Automatic type deduction, to be used as: + * QEMU_TYPEOF(expr) name = expr; + */ +#if QEMU_GNUC_PREREQ(4, 9) +# define QEMU_TYPEOF(a) __auto_type +#else +# define QEMU_TYPEOF(a) typeof(a) +#endif + #endif /* COMPILER_H */ diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 3bf48bcdec0..821ce627f73 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -232,18 +232,48 @@ extern int daemon(int, int); #define SIZE_MAX ((size_t)-1) #endif -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif +/* + * Two variations of MIN/MAX macros. The first is for runtime use, and + * evaluates arguments only once (so it is safe even with side + * effects), but will not work in constant contexts (such as array + * size declarations). The second is for compile-time use, where + * evaluating arguments twice is safe because the result is going to + * be constant anyway. + */ +#undef MIN +#define MIN(a, b) \ + ({ \ + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ + _a < _b ? _a : _b; \ + }) +#define MIN_CONST(a, b) \ + __builtin_choose_expr( \ + __builtin_constant_p(a) && __builtin_constant_p(b), \ + (a) < (b) ? (a) : (b), \ + __builtin_unreachable()) +#undef MAX +#define MAX(a, b) \ + ({ \ + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ + _a > _b ? _a : _b; \ + }) +#define MAX_CONST(a, b) \ + __builtin_choose_expr( \ + __builtin_constant_p(a) && __builtin_constant_p(b), \ + (a) > (b) ? (a) : (b), \ + __builtin_unreachable()) /* Minimum function that returns zero only iff both values are zero. * Intended for use with unsigned values only. */ #ifndef MIN_NON_ZERO -#define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \ - ((b) == 0 ? (a) : (MIN(a, b)))) +#define MIN_NON_ZERO(a, b) \ + ({ \ + QEMU_TYPEOF((a) + 0) _a = (a) + 0; \ + QEMU_TYPEOF((b) + 0) _b = (b) + 0; \ + _a == 0 ? _b : (_b == 0 || _b > _a) ? _a : _b; \ + }) #endif /* Round number down to multiple */ diff --git a/migration/qemu-file.c b/migration/qemu-file.c index 977b9ae07c1..9746cbec0f3 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -31,7 +31,7 @@ #include "trace.h" #define IO_BUF_SIZE 32768 -#define MAX_IOV_SIZE MIN(IOV_MAX, 64) +#define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 64) struct QEMUFile { const QEMUFileOps *ops;
Add the macro QEMU_TYPEOF() to access __auto_type in new enough compilers, while falling back to typeof on older compilers (the fallback doesn't handle variable length arrays, but we don't use those; it also expands to more text). Then use that macro to make MIN/MAX only evaluate their argument once; this uses type promotion (by adding to 0) to work around the fact that typeof(bitfield) won't compile. However, we are unable to work around gcc refusing to compile ({}) in a constant context, even when only used in the dead branch of a __builtin_choose_expr(), so we have to provide a second macro pair MIN_CONST and MAX_CONST for use when both arguments are known to be compile-time constants and where the result must also be usable in constant contexts. Fix the resulting callsites that compute a compile-time constant min or max to use the new macros. Signed-off-by: Eric Blake <eblake@redhat.com> --- v2: Force use of our smart macros, and make macro handle bitfields, constant expressions, and older compilers [Zoltan] --- hw/usb/hcd-xhci.h | 2 +- include/exec/cpu-defs.h | 2 +- include/qemu/compiler.h | 10 +++++++++ include/qemu/osdep.h | 46 ++++++++++++++++++++++++++++++++++------- migration/qemu-file.c | 2 +- 5 files changed, 51 insertions(+), 11 deletions(-)