[9] RFR(S): 8049043: Load variable through a pointer of an incompatible type in hotspot/src/share/vm/runtime/sharedRuntimeMath.hpp
David Chase
david.r.chase at oracle.com
Wed Jul 23 20:00:42 UTC 2014
It occurred to me that a cleaner way is to put the ifdef in the definition of the union:
typedef union {
double d;
struct {
#ifdef VM_LITTLE_ENDIAN
int lo;
int hi;
#else
int hi;
int lo;
#endif
};
} DoubleIntConv;
# define __HI(x) (x.hi)
# define __LO(x) (x.lo)
At which point, the continued use of the macro starts to look perhaps a hair silly.
I was inspired to write the following test program and compile it under clang and gcc (but not under Solaris Studio yet) to see if we could instead just write a stinking static method (that would be inlined) and at clang -O3 and gcc -O4, it was indeed inlined. So we could just write clean code and to heck with the macro. (Aren’t you loving this review process? :-)
We would, however, suffer some slowdown in slowdebug builds.
----------------------
#define VM_LITTLE_ENDIAN 1
typedef union {
double d;
struct {
#ifdef VM_LITTLE_ENDIAN
int lo;
int hi;
#else
int hi;
int lo;
#endif
};
} DoubleIntConv;
# define __HI(x) (x.hi)
# define __LO(x) (x.lo)
static int inline_low(double d) {
DoubleIntConv x = { d } ;
return __LO(x);
}
static int inline_high(double d) {
DoubleIntConv x = { d } ;
return __HI(x);
}
int low(double d) {
return inline_low(d);
}
int high(double d) {
return inline_high(d);
}
----------------------
On Jul 23, 2014, at 3:37 PM, Vladimir Kozlov <vladimir.kozlov at oracle.com> wrote:
> David, I agree with your suggestion to pass union to _HI and _LO. The creation of a local union var makes sense then.
>
> Thanks,
> Vladimir
>
> On 7/23/14 12:30 PM, David Chase wrote:
>> Vladimir, I think the mistake is instead to include the cast to the type
>> that it already is.
>> I think performing the cast to the union type from a non-union address
>> might get you a warning otherwise.
>> I can confirm that if you write it plainly with the assignment to a
>> correctly typed “conv”
>> that clang (at least) generates good code:
>>
>> union ca {
>> double d;
>> int i[2];
>> };
>>
>> int la(double d) {
>> union ca x = { d } ;
>> return x.i[0];
>> }
>>
>> clang produces (-O3 -S, cleaned up)
>>
>> _la: ## @la
>> pushq %rbp
>> movq %rsp, %rbp
>> movd %xmm0, %rax
>> popq %rbp
>> ret
>> gcc 4.8.1 produces (-O4 -S, cleaned up)
>>
>> la:
>> movsd%xmm0, -8(%rsp)
>> movq-8(%rsp), %rax
>> ret
>>
>> So I think this is generally a good idea, but the macro should be
>> cleaned up to
>> remove the cast that is certainly unnecessary now. E.g.
>>
>> 39 #ifdef VM_LITTLE_ENDIAN
>> 40 # define __HI(x) ((x).i[1])
>> 41 # define __LO(x) ((x).i[0])
>> 42 #else
>> 43 # define __HI(x) (x.i[0])
>> 44 # define __LO(x) (x.i[1])
>> 45 #endif
>>
>> The temporary is only annoying to humans using a last-millenium dialect
>> of C. The code runs fast, and the address-of+dereference in the macro
>> forced it to memory (lacking a lot of alias analysis) anyhow.
>>
>> David
>>
>>
>> On Jul 23, 2014, at 1:58 PM, Vladimir Kozlov <vladimir.kozlov at oracle.com
>> <mailto:vladimir.kozlov at oracle.com>> wrote:
>>
>>> Tobias, why you are creating local copy 'conv' of a variable in all
>>> places?
>>>
>>> Vladimir
>>>
>>> On 7/23/14 4:12 AM, Tobias Hartmann wrote:
>>>> Hi,
>>>>
>>>> please review the following patch for JDK- 8049043 (Parfait warning).
>>>>
>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8049043
>>>> Webrev: http://cr.openjdk.java.net/~thartmann/8049043/webrev.01/
>>>>
>>>> Problem:
>>>> Parfait issues 6 warnings " Load variable through a pointer of an
>>>> incompatible type" because of the __HI(x) and __LO(x) macros used in
>>>> copysignA and scalbnA (share/vm/runtime/sharedRuntimeMath.hpp) to cast
>>>> between double* and int*.
>>>>
>>>> Solution:
>>>> A union 'DoubleIntConv' is used to access the high and low 32 bits of a
>>>> double.
>>>> The '# pragma warning( disable: 4748 )' in sharedRuntimeTrans.cpp is
>>>> necessary because otherwise the VS compiler fails with the following
>>>> warning: "/GS can not protect parameters and local variables from local
>>>> buffer overrun because optimizations are disabled in function". There
>>>> exists a bug to fix this [1].
>>>>
>>>> Testing:
>>>> JPRT, Parfait (all 6 warnings removed)
>>>>
>>>> Thanks,
>>>> Tobias
>>>>
>>>> [1] https://bugs.openjdk.java.net/browse/JDK-8046696
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20140723/d4f6c896/signature.asc>
More information about the hotspot-compiler-dev
mailing list