@@ -244,7 +244,7 @@ class GEPLowering : public FunctionPass {
244244protected:
245245 // Helpers
246246 Value *getSExtOrTrunc (Value *, Type *) const ;
247- Value *truncExpr (Value *, Type *) const ;
247+ Value *truncExpr (Value *, Type *, bool ) const ;
248248
249249 bool simplifyGEP (BasicBlock &BB) const ;
250250 bool lowerGetElementPtrInst (GetElementPtrInst *GEP) const ;
@@ -578,15 +578,15 @@ Value *GEPLowering::getSExtOrTrunc(Value *Val, Type *NewTy) const {
578578 }
579579
580580 if (OldWidth > NewWidth) { // Trunc
581- return truncExpr (Val, NewTy);
581+ return truncExpr (Val, NewTy, true );
582582 }
583583
584584 return Val;
585585}
586586
587- Value *GEPLowering::truncExpr (Value *Val, Type *NewTy) const {
587+ Value *GEPLowering::truncExpr (Value *Val, Type *NewTy, bool initialVal = false ) const {
588588 // Truncation on Gen could be as cheap as NOP by creating the proper region.
589- // Instead of truncating the value itself, try to truncate how it's
589+ // Instead of truncating the value itself unless it has multiple users , try to truncate how it's
590590 // calculated.
591591 if (Constant *C = dyn_cast<Constant>(Val))
592592 return Builder->CreateIntCast (C, NewTy, false );
@@ -603,6 +603,12 @@ Value *GEPLowering::truncExpr(Value *Val, Type *NewTy) const {
603603 case Instruction::And:
604604 case Instruction::Or:
605605 case Instruction::Xor: {
606+ // If the value is used in multiple places, we can just re-use it without duplicating calculation since it can not
607+ // be removed.
608+ if (initialVal &&
609+ llvm::any_of (Val->users (), [](const llvm::User *U) { return !llvm::isa<llvm::GetElementPtrInst>(U); })) {
610+ return Builder->CreateTrunc (Val, NewTy);
611+ }
606612 BinaryOperator *BO = cast<BinaryOperator>(I);
607613 Value *LHS = truncExpr (BO->getOperand (0 ), NewTy);
608614 Value *RHS = truncExpr (BO->getOperand (1 ), NewTy);
0 commit comments