mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 09:31:03 +03:00
Add inbounds where possible
This commit is contained in:
parent
53cd715530
commit
eedde0ab16
3 changed files with 61 additions and 5 deletions
|
@ -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)));
|
||||||
|
|
|
@ -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
56
tests/codegen/inbounds.d
Normal 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;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue