Index: lib/Analysis/ConstantFolding.cpp =================================================================== --- lib/Analysis/ConstantFolding.cpp +++ lib/Analysis/ConstantFolding.cpp @@ -138,8 +138,15 @@ // The code below only handles casts to vectors currently. auto *DestVTy = dyn_cast(DestTy); - if (!DestVTy) - return ConstantExpr::getBitCast(C, DestTy); + if (!DestVTy) { + Constant *NewC = ConstantExpr::getBitCast(C, DestTy); + // If bitcast was converted to GEP, fold with data layout to normalize + // index types. + if (isa(NewC)) + if (Constant *FoldedGEP = ConstantFoldConstant(NewC, DL)) + return FoldedGEP; + return NewC; + } // If this is a scalar -> vector cast, convert the input into a <1 x scalar> // vector so the code below can handle it uniformly. @@ -1368,8 +1375,19 @@ case Instruction::SIToFP: case Instruction::FPToUI: case Instruction::FPToSI: - case Instruction::AddrSpaceCast: - return ConstantExpr::getCast(Opcode, C, DestTy); + return ConstantExpr::getCast(Opcode, C, DestTy); + case Instruction::AddrSpaceCast: { + Constant *NewC = ConstantExpr::getCast(Opcode, C, DestTy); + // Operand of addrspacecast may have been converted to a GEP, perform + // constant folding to normalize index types. Only do this if the + // addrspacecast operand is not C, as we'd recurse infinitely otherwise. + if (ConstantExpr *NewCE = dyn_cast(NewC)) + if (NewCE->getOpcode() == Instruction::AddrSpaceCast && + NewCE->getOperand(0) != C) + if (Constant *FoldedC = ConstantFoldConstant(NewC, DL)) + return FoldedC; + return NewC; + } case Instruction::BitCast: return FoldBitCast(C, DestTy, DL); } Index: test/Transforms/ConstProp/bitcast.ll =================================================================== --- test/Transforms/ConstProp/bitcast.ll +++ test/Transforms/ConstProp/bitcast.ll @@ -77,7 +77,7 @@ define i8* @bitcast_to_gep() { ; CHECK-LABEL: @bitcast_to_gep( -; CHECK-NEXT: ret i8* getelementptr inbounds (%T, %T* @G, i32 0, i32 0) +; CHECK-NEXT: ret i8* getelementptr inbounds (%T, %T* @G, i64 0, i32 0) ; %p = bitcast %T* @G to i8* ret i8* %p @@ -85,7 +85,7 @@ define i8 addrspace(1)* @addrspacecast_to_gep() { ; CHECK-LABEL: @addrspacecast_to_gep( -; CHECK-NEXT: ret i8 addrspace(1)* addrspacecast (i8* getelementptr inbounds (%T, %T* @G, i32 0, i32 0) to i8 addrspace(1)*) +; CHECK-NEXT: ret i8 addrspace(1)* addrspacecast (i8* getelementptr inbounds (%T, %T* @G, i64 0, i32 0) to i8 addrspace(1)*) ; %p = addrspacecast %T* @G to i8 addrspace(1)* ret i8 addrspace(1)* %p