Skip to content

Commit 8006b95

Browse files
authored
Fix miscompilation when adding a 64-bit constant to a symbol (#4283)
Fixes #4264
1 parent 5fd86e5 commit 8006b95

File tree

5 files changed

+31
-3
lines changed

5 files changed

+31
-3
lines changed

gen/toir.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,15 +847,21 @@ class ToElemVisitor : public Visitor {
847847
uint64_t elemSize = gDataLayout->getTypeAllocSize(elemType);
848848
if (e->offset % elemSize == 0) {
849849
// We can turn this into a "nice" GEP.
850-
offsetValue = DtoGEP1(DtoType(base->type), baseValue, e->offset / elemSize);
850+
if (elemType->isStructTy()) {
851+
// LLVM getelementptr requires that offsets are 32-bit constants
852+
// when the base type is a struct.
853+
offsetValue = DtoGEP1(DtoType(base->type), baseValue, e->offset / elemSize);
854+
} else {
855+
offsetValue = DtoGEP1i64(DtoType(base->type), baseValue, e->offset / elemSize);
856+
}
851857
}
852858
}
853859

854860
if (!offsetValue) {
855861
// Offset isn't a multiple of base type size, just cast to i8* and
856862
// apply the byte offset.
857863
offsetValue =
858-
DtoGEP1(LLType::getInt8Ty(gIR->context()),
864+
DtoGEP1i64(LLType::getInt8Ty(gIR->context()),
859865
DtoBitCast(baseValue, getVoidPtrType()), e->offset);
860866
}
861867
}

gen/tollvm.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,11 @@ LLConstant *DtoGEP(LLType *pointeeTy, LLConstant *ptr, unsigned i0,
385385
/* InBounds = */ true);
386386
}
387387

388+
LLValue *DtoGEP1i64(LLType *pointeeTy, LLValue *ptr, uint64_t i0, const char *name,
389+
llvm::BasicBlock *bb) {
390+
return DtoGEP(pointeeTy, ptr, DtoConstUlong(i0), name, bb);
391+
}
392+
388393
////////////////////////////////////////////////////////////////////////////////
389394

390395
void DtoMemSet(LLValue *dst, LLValue *val, LLValue *nbytes, unsigned align) {
@@ -450,6 +455,12 @@ LLValue *DtoMemCmp(LLValue *lhs, LLValue *rhs, LLValue *nbytes) {
450455
llvm::ConstantInt *DtoConstSize_t(uint64_t i) {
451456
return LLConstantInt::get(DtoSize_t(), i, false);
452457
}
458+
llvm::ConstantInt *DtoConstUlong(uint64_t i) {
459+
return LLConstantInt::get(LLType::getInt64Ty(gIR->context()), i, false);
460+
}
461+
llvm::ConstantInt *DtoConstLong(int64_t i) {
462+
return LLConstantInt::get(LLType::getInt64Ty(gIR->context()), i, true);
463+
}
453464
llvm::ConstantInt *DtoConstUint(unsigned i) {
454465
return LLConstantInt::get(LLType::getInt32Ty(gIR->context()), i, false);
455466
}

gen/tollvm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,13 @@ LLValue *DtoGEP(LLType *pointeeTy, LLValue *ptr, unsigned i0, unsigned i1,
9595
LLConstant *DtoGEP(LLType *pointeeTy, LLConstant *ptr, unsigned i0,
9696
unsigned i1);
9797

98+
LLValue *DtoGEP1i64(LLType *pointeeTy, LLValue *ptr, uint64_t i0,
99+
const char *name = "", llvm::BasicBlock *bb = nullptr);
100+
98101
// to constant helpers
99102
LLConstantInt *DtoConstSize_t(uint64_t);
103+
LLConstantInt *DtoConstUlong(uint64_t i);
104+
LLConstantInt *DtoConstLong(int64_t i);
100105
LLConstantInt *DtoConstUint(unsigned i);
101106
LLConstantInt *DtoConstInt(int i);
102107
LLConstantInt *DtoConstUbyte(unsigned char i);

tests/codegen/gh2865.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
void foo()
44
{
5-
// CHECK: %1 = getelementptr inbounds i8,{{.*}}_D6gh28653fooFZv{{.*}}, i32 -10
5+
// CHECK: %1 = getelementptr inbounds i8,{{.*}}_D6gh28653fooFZv{{.*}}, i64 -10
66
// CHECK-NEXT: %2 = ptrtoint {{i8\*|ptr}} %1 to i{{32|64}}
77
auto addr = (cast(size_t) &foo) - 10;
88
}

tests/codegen/gh4264.d

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %ldc -run %s
2+
3+
enum offset = 0xFFFF_FFFF_0000_0000UL;
4+
void main() {
5+
assert((cast(ulong)&main) != (cast(ulong)&main + offset));
6+
}

0 commit comments

Comments
 (0)