diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index f7558238d3..a33d0785e1 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1860,7 +1860,12 @@ DLValue *DtoIndexAggregate(LLValue *src, AggregateDeclaration *ad, LLType * ty = nullptr; if (!isFieldIdx) { // apply byte-wise offset from object start - ptr = DtoGEP1(getI8Type(), ptr, off); + ptr = DtoGEP1(getI8Type(), ptr, off +#if LDC_LLVM_VER >= 2000 + , "", nullptr + , llvm::GEPNoWrapFlags::inBounds() | llvm::GEPNoWrapFlags::noUnsignedWrap() +#endif + ); ty = DtoType(vd->type); } else { if (ad->structsize == 0) { // can happen for extern(C) structs @@ -1874,7 +1879,12 @@ DLValue *DtoIndexAggregate(LLValue *src, AggregateDeclaration *ad, } else { st = irTypeAggr->getLLType(); } - ptr = DtoGEP(st, ptr, 0, off); + ptr = DtoGEP(st, ptr, 0, off +#if LDC_LLVM_VER >= 2000 + , "", nullptr + , llvm::GEPNoWrapFlags::inBounds() | llvm::GEPNoWrapFlags::noUnsignedWrap() +#endif + ); ty = isaStruct(st)->getElementType(off); } } diff --git a/gen/toir.cpp b/gen/toir.cpp index fc8d65a854..603128ec79 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1190,7 +1190,16 @@ class ToElemVisitor : public Visitor { } LLType *elt = DtoMemType(e1type->nextOf()); LLType *arrty = llvm::ArrayType::get(elt, e1type->isTypeSArray()->dim->isIntegerExp()->getInteger()); - arrptr = DtoGEP(arrty, DtoLVal(l), DtoConstUint(0), DtoRVal(r)); +#if LDC_LLVM_VER >= 2000 + llvm::GEPNoWrapFlags nw = llvm::GEPNoWrapFlags::inBounds(); + if (e->indexIsInBounds) + nw |= llvm::GEPNoWrapFlags::noUnsignedWrap(); +#endif + arrptr = DtoGEP(arrty, DtoLVal(l), DtoConstUint(0), DtoRVal(r) +#if LDC_LLVM_VER >= 2000 + , "", nullptr, nw +#endif + ); } else if (e1type->ty == TY::Tarray) { if (p->emitArrayBoundsChecks() && !e->indexIsInBounds) { DtoIndexBoundsCheck(e->loc, l, r); @@ -1284,8 +1293,16 @@ class ToElemVisitor : public Visitor { } // offset by lower - eptr = DtoGEP1(DtoMemType(etype->nextOf()), getBasePointer(), vlo, "lowerbound"); - +#if LDC_LLVM_VER >= 2000 + llvm::GEPNoWrapFlags nw = llvm::GEPNoWrapFlags::inBounds(); + if (!needCheckUpper && !needCheckLower) + nw |= llvm::GEPNoWrapFlags::noUnsignedWrap(); +#endif + eptr = DtoGEP1(DtoMemType(etype->nextOf()), getBasePointer(), vlo, "lowerbound" +#if LDC_LLVM_VER >= 2000 + , nullptr, nw +#endif + ); // adjust length elen = p->ir->CreateSub(vup, vlo); } diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 63465ed887..fd5a5f9109 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -357,46 +357,103 @@ LLIntegerType *DtoSize_t() { namespace { llvm::GetElementPtrInst *DtoGEP(LLType *pointeeTy, LLValue *ptr, llvm::ArrayRef indices, - const char *name, llvm::BasicBlock *bb) { + const char *name, llvm::BasicBlock *bb +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw +#endif + ) { auto gep = llvm::GetElementPtrInst::Create(pointeeTy, ptr, indices, name, bb ? bb : gIR->scopebb()); +#if LDC_LLVM_VER >= 2000 + gep->setNoWrapFlags(nw); +#else gep->setIsInBounds(true); +#endif return gep; } } LLValue *DtoGEP1(LLType *pointeeTy, LLValue *ptr, LLValue *i0, const char *name, - llvm::BasicBlock *bb) { - return DtoGEP(pointeeTy, ptr, i0, name, bb); + llvm::BasicBlock *bb +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw +#endif + ) { + return DtoGEP(pointeeTy, ptr, i0, name, bb +#if LDC_LLVM_VER >= 2000 + , nw +#endif + ); } LLValue *DtoGEP(LLType *pointeeTy, LLValue *ptr, LLValue *i0, LLValue *i1, - const char *name, llvm::BasicBlock *bb) { + const char *name, llvm::BasicBlock *bb +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw +#endif + ) { LLValue *indices[] = {i0, i1}; - return DtoGEP(pointeeTy, ptr, indices, name, bb); + return DtoGEP(pointeeTy, ptr, indices, name, bb +#if LDC_LLVM_VER >= 2000 + , nw +#endif + ); } LLValue *DtoGEP1(LLType *pointeeTy, LLValue *ptr, unsigned i0, const char *name, - llvm::BasicBlock *bb) { - return DtoGEP(pointeeTy, ptr, DtoConstUint(i0), name, bb); + llvm::BasicBlock *bb +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw +#endif + ) { + return DtoGEP(pointeeTy, ptr, DtoConstUint(i0), name, bb +#if LDC_LLVM_VER >= 2000 + , nw +#endif + ); } LLValue *DtoGEP(LLType *pointeeTy, LLValue *ptr, unsigned i0, unsigned i1, - const char *name, llvm::BasicBlock *bb) { + const char *name, llvm::BasicBlock *bb +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw +#endif + ) { LLValue *indices[] = {DtoConstUint(i0), DtoConstUint(i1)}; - return DtoGEP(pointeeTy, ptr, indices, name, bb); + return DtoGEP(pointeeTy, ptr, indices, name, bb +#if LDC_LLVM_VER >= 2000 + , nw +#endif + ); } LLConstant *DtoGEP(LLType *pointeeTy, LLConstant *ptr, unsigned i0, - unsigned i1) { + unsigned i1 +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw +#endif + ) { LLValue *indices[] = {DtoConstUint(i0), DtoConstUint(i1)}; return llvm::ConstantExpr::getGetElementPtr(pointeeTy, ptr, indices, - /* InBounds = */ true); +#if LDC_LLVM_VER >= 2000 + nw +#else + /* InBounds = */ true +#endif + ); } LLValue *DtoGEP1i64(LLType *pointeeTy, LLValue *ptr, uint64_t i0, const char *name, - llvm::BasicBlock *bb) { - return DtoGEP(pointeeTy, ptr, DtoConstUlong(i0), name, bb); + llvm::BasicBlock *bb +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw +#endif + ) { + return DtoGEP(pointeeTy, ptr, DtoConstUlong(i0), name, bb +#if LDC_LLVM_VER >= 2000 + , nw +#endif + ); } //////////////////////////////////////////////////////////////////////////////// @@ -701,7 +758,7 @@ LLGlobalVariable *makeGlobal(LLStringRef name, LLType* type, LLStringRef section if (!section.empty()) var->setSection(section); - + return var; } @@ -737,7 +794,7 @@ LLGlobalVariable *makeGlobalWithBytes(LLStringRef name, LLConstantList packedCon 0u, externInit ); - + return var; } diff --git a/gen/tollvm.h b/gen/tollvm.h index 14d22d38d4..373c91f844 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -77,19 +77,43 @@ LLStructType *DtoModuleReferenceType(); // getelementptr helpers LLValue *DtoGEP1(LLType *pointeeTy, LLValue *ptr, LLValue *i0, - const char *name = "", llvm::BasicBlock *bb = nullptr); + const char *name = "", llvm::BasicBlock *bb = nullptr +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw = llvm::GEPNoWrapFlags::inBounds() +#endif + ); LLValue *DtoGEP(LLType *pointeeTy, LLValue *ptr, LLValue *i0, LLValue *i1, - const char *name = "", llvm::BasicBlock *bb = nullptr); + const char *name = "", llvm::BasicBlock *bb = nullptr +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw = llvm::GEPNoWrapFlags::inBounds() +#endif + ); LLValue *DtoGEP1(LLType *pointeeTy, LLValue *ptr, unsigned i0, - const char *name = "", llvm::BasicBlock *bb = nullptr); + const char *name = "", llvm::BasicBlock *bb = nullptr +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw = llvm::GEPNoWrapFlags::inBounds() +#endif + ); LLValue *DtoGEP(LLType *pointeeTy, LLValue *ptr, unsigned i0, unsigned i1, - const char *name = "", llvm::BasicBlock *bb = nullptr); + const char *name = "", llvm::BasicBlock *bb = nullptr +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw = llvm::GEPNoWrapFlags::inBounds() +#endif + ); LLConstant *DtoGEP(LLType *pointeeTy, LLConstant *ptr, unsigned i0, - unsigned i1); + unsigned i1 +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw = llvm::GEPNoWrapFlags::inBounds() +#endif + ); LLValue *DtoGEP1i64(LLType *pointeeTy, LLValue *ptr, uint64_t i0, - const char *name = "", llvm::BasicBlock *bb = nullptr); + const char *name = "", llvm::BasicBlock *bb = nullptr +#if LDC_LLVM_VER >= 2000 + , llvm::GEPNoWrapFlags nw = llvm::GEPNoWrapFlags::inBounds() +#endif + ); // to constant helpers LLConstantInt *DtoConstSize_t(uint64_t); diff --git a/tests/codegen/inbounds.d b/tests/codegen/inbounds.d index d50939f71b..e92b7bd476 100644 --- a/tests/codegen/inbounds.d +++ b/tests/codegen/inbounds.d @@ -9,7 +9,7 @@ extern(C): // Avoid name mangling // IndexExp in static array with const exp // CHECK-LABEL: @foo1 int foo1(int[3] a) { - // CHECK: getelementptr inbounds [3 x i32] + // CHECK: getelementptr inbounds{{( nuw)?}} [3 x i32] return a[1]; } @@ -58,7 +58,7 @@ int foo7(int* p, int i) { // Struct field // CHECK-LABEL: @foo8 float foo8(S s) { - // CHECK: getelementptr inbounds + // CHECK: getelementptr inbounds{{( nuw)?}} return s.y; } @@ -79,7 +79,7 @@ int foo10(int[] a, int i) { // SliceExp for static array with const lower bound // CHECK-LABEL: @foo11 int[] foo11(ref int[3] a) { - // CHECK: getelementptr inbounds i32, ptr + // CHECK: getelementptr inbounds{{( nuw)?}} i32, ptr return a[1 .. $]; }