diff --git a/opt.cpp b/opt.cpp index 5f77daa8..0ec7dd67 100644 --- a/opt.cpp +++ b/opt.cpp @@ -1220,12 +1220,24 @@ char ImproveMemoryOpsPass::ID = 0; */ static llvm::Value * lCheckForActualPointer(llvm::Value *v) { - if (v == NULL) + if (v == NULL) { return NULL; - else if (llvm::isa(v->getType())) + } + else if (llvm::isa(v->getType())) { return v; - else if (llvm::isa(v)) + } + else if (llvm::isa(v)) { return v; + } + else if (llvm::CastInst *ci = llvm::dyn_cast(v)) { + llvm::Value *t = lCheckForActualPointer(ci->getOperand(0)); + if (t == NULL) { + return NULL; + } + else { + return v; + } + } else { llvm::ConstantExpr *uce = llvm::dyn_cast(v); @@ -1243,7 +1255,7 @@ lCheckForActualPointer(llvm::Value *v) { pointer value; otherwise it returns NULL. */ static llvm::Value * -lGetBasePointer(llvm::Value *v) { +lGetBasePointer(llvm::Value *v, llvm::Instruction *insertBefore) { if (llvm::isa(v) || llvm::isa(v)) { llvm::Value *element = LLVMFlattenInsertChain @@ -1267,6 +1279,20 @@ lGetBasePointer(llvm::Value *v) { else if (llvm::ConstantDataVector *cdv = llvm::dyn_cast(v)) { return lCheckForActualPointer(cdv->getSplatValue()); } + // It is a little bit tricky to use operations with pointers, casted to int with another bit size + // but sometimes it is useful, so we handle this case here. + else if (llvm::CastInst *ci = llvm::dyn_cast(v)) { + llvm::Value *t = lGetBasePointer(ci->getOperand(0), insertBefore); + if (t == NULL) { + return NULL; + } + else { + return llvm::CastInst::Create(ci->getOpcode(), + t, ci->getType()->getScalarType(), + LLVMGetName(t, "_cast"), + insertBefore); + } + } return NULL; } @@ -1320,7 +1346,7 @@ lGetBasePtrAndOffsets(llvm::Value *ptrs, llvm::Value **offsets, LLVMDumpValue(ptrs); } - llvm::Value *base = lGetBasePointer(ptrs); + llvm::Value *base = lGetBasePointer(ptrs, insertBefore); if (base != NULL) { // We have a straight up varying pointer with no indexing that's // actually all the same value. @@ -1456,30 +1482,30 @@ lExtractConstantOffset(llvm::Value *vec, llvm::Value **constOffset, return; } - llvm::SExtInst *sext = llvm::dyn_cast(vec); - if (sext != NULL) { - // Check the sext target. + llvm::CastInst *cast = llvm::dyn_cast(vec); + if (cast != NULL) { + // Check the cast target. llvm::Value *co, *vo; - lExtractConstantOffset(sext->getOperand(0), &co, &vo, insertBefore); + lExtractConstantOffset(cast->getOperand(0), &co, &vo, insertBefore); - // make new sext instructions for the two parts + // make new cast instructions for the two parts if (co == NULL) *constOffset = NULL; else - *constOffset = new llvm::SExtInst(co, sext->getType(), - LLVMGetName(co, "_sext"), + *constOffset = llvm::CastInst::Create(cast->getOpcode(), + co, cast->getType(), + LLVMGetName(co, "_cast"), insertBefore); if (vo == NULL) *variableOffset = NULL; else - *variableOffset = new llvm::SExtInst(vo, sext->getType(), - LLVMGetName(vo, "_sext"), + *variableOffset = llvm::CastInst::Create(cast->getOpcode(), + vo, cast->getType(), + LLVMGetName(vo, "_cast"), insertBefore); return; } - // FIXME? handle bitcasts / type casts here - llvm::BinaryOperator *bop = llvm::dyn_cast(vec); if (bop != NULL) { llvm::Value *op0 = bop->getOperand(0); @@ -1671,17 +1697,17 @@ lExtract248Scale(llvm::Value *splatOperand, int splatValue, */ static llvm::Value * lExtractOffsetVector248Scale(llvm::Value **vec) { - llvm::SExtInst *sext = llvm::dyn_cast(*vec); - if (sext != NULL) { - llvm::Value *sextOp = sext->getOperand(0); - // Check the sext target. - llvm::Value *scale = lExtractOffsetVector248Scale(&sextOp); + llvm::CastInst *cast = llvm::dyn_cast(*vec); + if (cast != NULL) { + llvm::Value *castOp = cast->getOperand(0); + // Check the cast target. + llvm::Value *scale = lExtractOffsetVector248Scale(&castOp); if (scale == NULL) return NULL; - // make a new sext instruction so that we end up with the right + // make a new cast instruction so that we end up with the right // type - *vec = new llvm::SExtInst(sextOp, sext->getType(), "offset_sext", sext); + *vec = llvm::CastInst::Create(cast->getOpcode(), castOp, cast->getType(), "offset_cast", cast); return scale; } diff --git a/tests/ptr-int-1.ispc b/tests/ptr-int-1.ispc index 1ffbc02f..cdcb8807 100644 --- a/tests/ptr-int-1.ispc +++ b/tests/ptr-int-1.ispc @@ -5,7 +5,7 @@ export uniform int width() { return programCount; } export void f_f(uniform float RET[], uniform float aFOO[]) { uniform int a = 1; uniform int * uniform b = &a; - int64 pi = (int64)b; + uintptr_t pi = (uintptr_t)b; RET[programIndex] = *((uniform int * varying)pi); }