- const Instruction *I = dyn_cast<Instruction>(V1);
- const Value *NoopInput = 0;
- if (I != 0 && I->getNumOperands() > 0) {
- Value *Op = I->getOperand(0);
- if (isa<TruncInst>(I)) {
- // Look through truly no-op truncates.
- if (TLI.isTruncateFree(Op->getType(), I->getType()))
- NoopInput = Op;
- } else if (isa<BitCastInst>(I)) {
- // Look through truly no-op bitcasts.
- if (isNoopBitcast(Op->getType(), I->getType(), TLI))
- NoopInput = Op;
- } else if (isa<GetElementPtrInst>(I)) {
- // Look through getelementptr
- if (cast<GetElementPtrInst>(I)->hasAllZeroIndices())
- NoopInput = Op;
- } else if (isa<IntToPtrInst>(I)) {
- // Look through inttoptr.
- // Make sure this isn't a truncating or extending cast. We could
- // support this eventually, but don't bother for now.
- if (!isa<VectorType>(I->getType()) &&
- TLI.getPointerTy().getSizeInBits() ==
- cast<IntegerType>(Op->getType())->getBitWidth())
- NoopInput = Op;
- } else if (isa<PtrToIntInst>(I)) {
- // Look through ptrtoint.
- // Make sure this isn't a truncating or extending cast. We could
- // support this eventually, but don't bother for now.
- if (!isa<VectorType>(I->getType()) &&
- TLI.getPointerTy().getSizeInBits() ==
- cast<IntegerType>(I->getType())->getBitWidth())
- NoopInput = Op;
+ const Instruction *I = dyn_cast<Instruction>(V);
+ if (!I || I->getNumOperands() == 0) return V;
+ const Value *NoopInput = nullptr;
+
+ Value *Op = I->getOperand(0);
+ if (isa<BitCastInst>(I)) {
+ // Look through truly no-op bitcasts.
+ if (isNoopBitcast(Op->getType(), I->getType(), TLI))
+ NoopInput = Op;
+ } else if (isa<GetElementPtrInst>(I)) {
+ // Look through getelementptr
+ if (cast<GetElementPtrInst>(I)->hasAllZeroIndices())
+ NoopInput = Op;
+ } else if (isa<IntToPtrInst>(I)) {
+ // Look through inttoptr.
+ // Make sure this isn't a truncating or extending cast. We could
+ // support this eventually, but don't bother for now.
+ if (!isa<VectorType>(I->getType()) &&
+ TLI.getPointerTy().getSizeInBits() ==
+ cast<IntegerType>(Op->getType())->getBitWidth())
+ NoopInput = Op;
+ } else if (isa<PtrToIntInst>(I)) {
+ // Look through ptrtoint.
+ // Make sure this isn't a truncating or extending cast. We could
+ // support this eventually, but don't bother for now.
+ if (!isa<VectorType>(I->getType()) &&
+ TLI.getPointerTy().getSizeInBits() ==
+ cast<IntegerType>(I->getType())->getBitWidth())
+ NoopInput = Op;
+ } else if (isa<TruncInst>(I) &&
+ TLI.allowTruncateForTailCall(Op->getType(), I->getType())) {
+ DataBits = std::min(DataBits, I->getType()->getPrimitiveSizeInBits());
+ NoopInput = Op;
+ } else if (isa<CallInst>(I)) {
+ // Look through call (skipping callee)
+ for (User::const_op_iterator i = I->op_begin(), e = I->op_end() - 1;
+ i != e; ++i) {
+ unsigned attrInd = i - I->op_begin() + 1;
+ if (cast<CallInst>(I)->paramHasAttr(attrInd, Attribute::Returned) &&
+ isNoopBitcast((*i)->getType(), I->getType(), TLI)) {
+ NoopInput = *i;
+ break;
+ }
+ }
+ } else if (isa<InvokeInst>(I)) {
+ // Look through invoke (skipping BB, BB, Callee)
+ for (User::const_op_iterator i = I->op_begin(), e = I->op_end() - 3;
+ i != e; ++i) {
+ unsigned attrInd = i - I->op_begin() + 1;
+ if (cast<InvokeInst>(I)->paramHasAttr(attrInd, Attribute::Returned) &&
+ isNoopBitcast((*i)->getType(), I->getType(), TLI)) {
+ NoopInput = *i;
+ break;
+ }