Skip to content

Commit 877406d

Browse files
committed
Fix a recent regression in atomics support
A recent update changed the types of the bit-fields in ATOMIC_INFO from unsigned int to enum types. This resulted in the values of those fields being incorrectly sign extended when extracted from the struct. Fix the problem by changing the fields of ATOMIC_INFO to not be bit-fields. This required changing the code that encodes/decodes ATOMIC_INFO to/from an int.
1 parent 445f4fd commit 877406d

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

tools/flang2/flang2exe/iliutil.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,17 @@
4949
*/
5050
#include "mth.h"
5151

52-
/** Union used to encode ATOMIC_INFO as an int or decode it. If
53-
sizeof(ATOMIC_INFO)>int, then the union trick cannot be used and we'll have
54-
to write explicit bit packing code. */
52+
/** Union used to encode ATOMIC_INFO as an int or decode it. The union
53+
contains a compacted version of ATOMIC_INFO using bitfields. The bitfields
54+
are unsigned rather than the proper enum type so that the values aren't
55+
sign extended when extracted. */
5556
union ATOMIC_ENCODER {
56-
ATOMIC_INFO info;
57+
struct {
58+
unsigned msz : 8;
59+
unsigned op : 8;
60+
unsigned origin : 2;
61+
unsigned scope : 1;
62+
} info;
5763
int encoding;
5864
};
5965

@@ -13637,7 +13643,7 @@ atomic_encode_aux(MSZ msz, SYNC_SCOPE scope, ATOMIC_ORIGIN origin,
1363713643
ATOMIC_RMW_OP op)
1363813644
{
1363913645
union ATOMIC_ENCODER u;
13640-
DEBUG_ASSERT(sizeof(ATOMIC_INFO) <= sizeof(int),
13646+
DEBUG_ASSERT(sizeof(u.info) <= sizeof(int),
1364113647
"need to reimplement atomic_encode");
1364213648
DEBUG_ASSERT((unsigned)origin <= (unsigned)AORG_MAX_DEF,
1364313649
"atomic_encode_ld_st: bad origin");
@@ -13679,9 +13685,14 @@ atomic_encode_rmw(MSZ msz, SYNC_SCOPE scope, ATOMIC_ORIGIN origin,
1367913685
ATOMIC_INFO
1368013686
atomic_decode(int encoding)
1368113687
{
13688+
ATOMIC_INFO result;
1368213689
union ATOMIC_ENCODER u;
1368313690
u.encoding = encoding;
13684-
return u.info;
13691+
result.msz = (MSZ) u.info.msz;
13692+
result.op = (ATOMIC_RMW_OP) u.info.op;
13693+
result.origin = (ATOMIC_ORIGIN) u.info.origin;
13694+
result.scope = (SYNC_SCOPE) u.info.scope;
13695+
return result;
1368513696
}
1368613697

1368713698
/** Get index of ATOMIC_INFO operand for a given ILI instruction. */

tools/shared/atomic_common.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
2+
* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -105,14 +105,12 @@ typedef struct CMPXCHG_MEMORY_ORDER {
105105
MEMORY_ORDER failure;
106106
} CMPXCHG_MEMORY_ORDER;
107107

108-
/** Information about an atomic operation.
109-
The fields are declared unsigned because pgcc/pgc++ 17.1 sign-extends
110-
them if they are declared as enum types. */
108+
/** Information about an atomic operation. */
111109
typedef struct ATOMIC_INFO {
112-
MSZ msz : 8; ///< size of memory operand
113-
ATOMIC_RMW_OP op : 8; ///< AOP_UNDEF except for ATOMICRMWx instructions
114-
ATOMIC_ORIGIN origin : 2;
115-
SYNC_SCOPE scope : 1;
110+
MSZ msz; ///< size of memory operand
111+
ATOMIC_RMW_OP op; ///< AOP_UNDEF except for ATOMICRMWx instructions
112+
ATOMIC_ORIGIN origin;
113+
SYNC_SCOPE scope;
116114
} ATOMIC_INFO;
117115

118116
/** True if MEMORY_ORDER m performs an acquire operation.

0 commit comments

Comments
 (0)