Add inbounds where possible

This commit is contained in:
Stefanos Baziotis 2019-08-31 03:23:03 +03:00 committed by Martin Kinkelin
parent 53cd715530
commit eedde0ab16
3 changed files with 61 additions and 5 deletions

View file

@ -115,7 +115,7 @@ DValue *emitPointerOffset(Loc loc, DValue *base, Expression *offset,
if (!llResult) { if (!llResult) {
if (negateOffset) if (negateOffset)
llOffset = gIR->ir->CreateNeg(llOffset); llOffset = gIR->ir->CreateNeg(llOffset);
llResult = DtoGEP1(llBase, llOffset, false); llResult = DtoGEP1(llBase, llOffset, /* inBounds = */ true);
} }
return new DImValue(resultType, DtoBitCast(llResult, DtoType(resultType))); return new DImValue(resultType, DtoBitCast(llResult, DtoType(resultType)));

View file

@ -1080,7 +1080,7 @@ public:
LLValue *arrptr = nullptr; LLValue *arrptr = nullptr;
if (e1type->ty == Tpointer) { if (e1type->ty == Tpointer) {
arrptr = DtoGEP1(DtoRVal(l), DtoRVal(r), false); arrptr = DtoGEP1(DtoRVal(l), DtoRVal(r), /* inBounds = */ true);
} else if (e1type->ty == Tsarray) { } else if (e1type->ty == Tsarray) {
if (p->emitArrayBoundsChecks() && !e->indexIsInBounds) { if (p->emitArrayBoundsChecks() && !e->indexIsInBounds) {
DtoIndexBoundsCheck(e->loc, l, r); DtoIndexBoundsCheck(e->loc, l, r);
@ -1420,7 +1420,7 @@ public:
assert(e->e2->op == TOKint64); assert(e->e2->op == TOKint64);
LLConstant *offset = LLConstant *offset =
e->op == TOKplusplus ? DtoConstUint(1) : DtoConstInt(-1); e->op == TOKplusplus ? DtoConstUint(1) : DtoConstInt(-1);
post = DtoGEP1(val, offset, false, "", p->scopebb()); post = DtoGEP1(val, offset, /* inBounds = */ true, "", p->scopebb());
} else if (e1type->iscomplex()) { } else if (e1type->iscomplex()) {
assert(e2type->iscomplex()); assert(e2type->iscomplex());
LLValue *one = LLConstantFP::get(DtoComplexBaseType(e1type), 1.0); LLValue *one = LLConstantFP::get(DtoComplexBaseType(e1type), 1.0);

56
tests/codegen/inbounds.d Normal file
View file

@ -0,0 +1,56 @@
// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
struct S {
float x, y;
};
extern(C): // Avoid name mangling
// IndexExp in array with const exp
// CHECK-LABEL: @foo1
int foo1(int[3] a) {
// CHECK: getelementptr inbounds [3 x i32]
return a[1];
}
// IndexExp in pointer
// CHECK-LABEL: @foo2
int foo2(int* p, int i) {
// CHECK: getelementptr inbounds
return p[i];
}
// PostExp in pointer
// CHECK-LABEL: @foo3
int foo3(int* p) {
// CHECK: getelementptr inbounds
return *p++;
}
// PreExp in pointer
// CHECK-LABEL: @foo4
int foo4(int* p) {
// CHECK: getelementptr inbounds
return *++p;
}
// Add offset to pointer
// CHECK-LABEL: @foo5
int foo5(int* p, int i) {
// CHECK: getelementptr inbounds
return *(p + i);
}
// Subtract offset from pointer
// CHECK-LABEL: @foo6
int foo6(int* p, int i) {
// CHECK: getelementptr inbounds
return *(p - i);
}
// Struct field
// CHECK-LABEL: @foo7
float foo7(S s) {
// CHECK: getelementptr inbounds
return s.y;
}