Skip to content

Commit 3192eb3

Browse files
authored
Merge pull request #22208 from linux-on-ibm-z/s390x-storetag-fix
Fix storeEnumTagSinglePayload on big-endian systems
2 parents 8702c23 + 43bfbd5 commit 3192eb3

File tree

3 files changed

+41
-41
lines changed

3 files changed

+41
-41
lines changed

lib/IRGen/EnumPayload.cpp

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -162,22 +162,22 @@ void EnumPayload::insertValue(IRGenFunction &IGF, llvm::Value *value,
162162
subvalue = IGF.Builder.CreateLShr(subvalue,
163163
llvm::ConstantInt::get(valueIntTy, valueOffset));
164164
subvalue = IGF.Builder.CreateZExtOrTrunc(subvalue, payloadIntTy);
165-
#if defined(__BIG_ENDIAN__)
166-
if ((valueBitWidth == 32 || valueBitWidth == 16 || valueBitWidth == 8 || valueBitWidth == 1) &&
167-
payloadBitWidth > (payloadValueOffset + valueBitWidth)) {
168-
unsigned shiftBitWidth = valueBitWidth;
169-
if (valueBitWidth == 1) {
170-
shiftBitWidth = 8;
165+
if (IGF.IGM.Triple.isLittleEndian()) {
166+
if (payloadValueOffset > 0)
167+
subvalue = IGF.Builder.CreateShl(subvalue,
168+
llvm::ConstantInt::get(payloadIntTy, payloadValueOffset));
169+
} else {
170+
if ((valueBitWidth == 32 || valueBitWidth == 16 || valueBitWidth == 8 || valueBitWidth == 1) &&
171+
payloadBitWidth > (payloadValueOffset + valueBitWidth)) {
172+
unsigned shiftBitWidth = valueBitWidth;
173+
if (valueBitWidth == 1) {
174+
shiftBitWidth = 8;
175+
}
176+
subvalue = IGF.Builder.CreateShl(subvalue,
177+
llvm::ConstantInt::get(payloadIntTy, (payloadBitWidth - shiftBitWidth) - payloadValueOffset));
171178
}
172-
subvalue = IGF.Builder.CreateShl(subvalue,
173-
llvm::ConstantInt::get(payloadIntTy, (payloadBitWidth - shiftBitWidth) - payloadValueOffset));
174179
}
175-
#else
176-
if (payloadValueOffset > 0)
177-
subvalue = IGF.Builder.CreateShl(subvalue,
178-
llvm::ConstantInt::get(payloadIntTy, payloadValueOffset));
179-
#endif
180-
180+
181181
// If there hasn't yet been a value stored here, we can use the adjusted
182182
// value directly.
183183
if (payloadValue.is<llvm::Type *>()) {
@@ -230,21 +230,21 @@ llvm::Value *EnumPayload::extractValue(IRGenFunction &IGF, llvm::Type *type,
230230
llvm::IntegerType::get(IGF.IGM.getLLVMContext(), payloadBitWidth);
231231

232232
value = IGF.Builder.CreateBitOrPointerCast(value, payloadIntTy);
233-
#if defined(__BIG_ENDIAN__)
234-
if ((valueBitWidth == 32 || valueBitWidth == 16 || valueBitWidth == 8 || valueBitWidth == 1) &&
235-
payloadBitWidth > (payloadValueOffset + valueBitWidth)) {
236-
unsigned shiftBitWidth = valueBitWidth;
237-
if (valueBitWidth == 1) {
238-
shiftBitWidth = 8;
233+
if (IGF.IGM.Triple.isLittleEndian()) {
234+
if (payloadValueOffset > 0)
235+
value = IGF.Builder.CreateLShr(value,
236+
llvm::ConstantInt::get(value->getType(), payloadValueOffset));
237+
} else {
238+
if ((valueBitWidth == 32 || valueBitWidth == 16 || valueBitWidth == 8 || valueBitWidth == 1) &&
239+
payloadBitWidth > (payloadValueOffset + valueBitWidth)) {
240+
unsigned shiftBitWidth = valueBitWidth;
241+
if (valueBitWidth == 1) {
242+
shiftBitWidth = 8;
243+
}
244+
value = IGF.Builder.CreateLShr(value,
245+
llvm::ConstantInt::get(value->getType(), (payloadBitWidth - shiftBitWidth) - payloadValueOffset));
239246
}
240-
value = IGF.Builder.CreateLShr(value,
241-
llvm::ConstantInt::get(value->getType(), (payloadBitWidth - shiftBitWidth) - payloadValueOffset));
242247
}
243-
#else
244-
if (payloadValueOffset > 0)
245-
value = IGF.Builder.CreateLShr(value,
246-
llvm::ConstantInt::get(value->getType(), payloadValueOffset));
247-
#endif
248248
if (valueBitWidth > payloadBitWidth)
249249
value = IGF.Builder.CreateZExt(value, valueIntTy);
250250
if (valueOffset > 0)

lib/IRGen/GenEnum.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4202,12 +4202,12 @@ namespace {
42024202
} else if (!CommonSpareBits.empty()) {
42034203
// Otherwise the payload is just the index.
42044204
payload = EnumPayload::zero(IGM, PayloadSchema);
4205-
#if defined(__BIG_ENDIAN__) && defined(__LP64__)
4206-
// Code produced above are of type IGM.Int32Ty
4207-
// However, payload is IGM.SizeTy in 64bit
4208-
if (numCaseBits >= 64)
4209-
tagIndex = IGF.Builder.CreateZExt(tagIndex, IGM.SizeTy);
4210-
#endif
4205+
if (!IGF.IGM.Triple.isLittleEndian()) {
4206+
if (IGF.IGM.Triple.isArch64Bit() && numCaseBits >= 64) {
4207+
// Need to set the full 64-bit chunk on big-endian systems.
4208+
tagIndex = IGF.Builder.CreateZExt(tagIndex, IGM.SizeTy);
4209+
}
4210+
}
42114211
// We know we won't use more than numCaseBits from tagIndex's value:
42124212
// We made sure of this in the logic above.
42134213
payload.insertValue(IGF, tagIndex, 0,

stdlib/public/runtime/EnumImpl.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,14 @@ inline void storeEnumTagSinglePayloadImpl(
170170

171171
// Store into the value.
172172
#if defined(__BIG_ENDIAN__)
173-
unsigned numPayloadTagBytes = std::min(size_t(4), payloadSize);
174-
if (numPayloadTagBytes)
175-
small_memcpy(valueAddr,
176-
reinterpret_cast<uint8_t *>(&payloadIndex) + 4 -
177-
numPayloadTagBytes,
178-
numPayloadTagBytes, true);
179-
if (payloadSize > 4)
180-
memset(valueAddr + 4, 0, payloadSize - 4);
173+
uint64_t payloadIndexBuf = static_cast<uint64_t>(payloadIndex);
174+
if (payloadSize >= 8) {
175+
memcpy(valueAddr, &payloadIndexBuf, 8);
176+
memset(valueAddr + 8, 0, payloadSize - 8);
177+
} else if (payloadSize > 0) {
178+
payloadIndexBuf <<= (8 - payloadSize) * 8;
179+
memcpy(valueAddr, &payloadIndexBuf, payloadSize);
180+
}
181181
if (numExtraTagBytes)
182182
small_memcpy(extraTagBitAddr,
183183
reinterpret_cast<uint8_t *>(&extraTagIndex) + 4 -

0 commit comments

Comments
 (0)