@@ -1013,6 +1013,9 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
1013
1013
if (Instruction::isBinaryOp (Opcode))
1014
1014
return ConstantFoldBinaryOpOperands (Opcode, Ops[0 ], Ops[1 ], DL);
1015
1015
1016
+ if (Instruction::isCast (Opcode))
1017
+ return ConstantFoldCastOperand (Opcode, Ops[0 ], DestTy, DL);
1018
+
1016
1019
switch (Opcode) {
1017
1020
default : return nullptr ;
1018
1021
case Instruction::ICmp:
@@ -1022,58 +1025,6 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
1022
1025
if (canConstantFoldCallTo (F))
1023
1026
return ConstantFoldCall (F, Ops.slice (0 , Ops.size () - 1 ), TLI);
1024
1027
return nullptr ;
1025
- case Instruction::PtrToInt:
1026
- // If the input is a inttoptr, eliminate the pair. This requires knowing
1027
- // the width of a pointer, so it can't be done in ConstantExpr::getCast.
1028
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0 ])) {
1029
- if (CE->getOpcode () == Instruction::IntToPtr) {
1030
- Constant *Input = CE->getOperand (0 );
1031
- unsigned InWidth = Input->getType ()->getScalarSizeInBits ();
1032
- unsigned PtrWidth = DL.getPointerTypeSizeInBits (CE->getType ());
1033
- if (PtrWidth < InWidth) {
1034
- Constant *Mask =
1035
- ConstantInt::get (CE->getContext (),
1036
- APInt::getLowBitsSet (InWidth, PtrWidth));
1037
- Input = ConstantExpr::getAnd (Input, Mask);
1038
- }
1039
- // Do a zext or trunc to get to the dest size.
1040
- return ConstantExpr::getIntegerCast (Input, DestTy, false );
1041
- }
1042
- }
1043
- return ConstantExpr::getCast (Opcode, Ops[0 ], DestTy);
1044
- case Instruction::IntToPtr:
1045
- // If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if
1046
- // the int size is >= the ptr size and the address spaces are the same.
1047
- // This requires knowing the width of a pointer, so it can't be done in
1048
- // ConstantExpr::getCast.
1049
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0 ])) {
1050
- if (CE->getOpcode () == Instruction::PtrToInt) {
1051
- Constant *SrcPtr = CE->getOperand (0 );
1052
- unsigned SrcPtrSize = DL.getPointerTypeSizeInBits (SrcPtr->getType ());
1053
- unsigned MidIntSize = CE->getType ()->getScalarSizeInBits ();
1054
-
1055
- if (MidIntSize >= SrcPtrSize) {
1056
- unsigned SrcAS = SrcPtr->getType ()->getPointerAddressSpace ();
1057
- if (SrcAS == DestTy->getPointerAddressSpace ())
1058
- return FoldBitCast (CE->getOperand (0 ), DestTy, DL);
1059
- }
1060
- }
1061
- }
1062
-
1063
- return ConstantExpr::getCast (Opcode, Ops[0 ], DestTy);
1064
- case Instruction::Trunc:
1065
- case Instruction::ZExt:
1066
- case Instruction::SExt:
1067
- case Instruction::FPTrunc:
1068
- case Instruction::FPExt:
1069
- case Instruction::UIToFP:
1070
- case Instruction::SIToFP:
1071
- case Instruction::FPToUI:
1072
- case Instruction::FPToSI:
1073
- case Instruction::AddrSpaceCast:
1074
- return ConstantExpr::getCast (Opcode, Ops[0 ], DestTy);
1075
- case Instruction::BitCast:
1076
- return FoldBitCast (Ops[0 ], DestTy, DL);
1077
1028
case Instruction::Select:
1078
1029
return ConstantExpr::getSelect (Ops[0 ], Ops[1 ], Ops[2 ]);
1079
1030
case Instruction::ExtractElement:
@@ -1188,6 +1139,67 @@ Constant *llvm::ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS,
1188
1139
return ConstantExpr::get (Opcode, LHS, RHS);
1189
1140
}
1190
1141
1142
+ Constant *llvm::ConstantFoldCastOperand (unsigned Opcode, Constant *C,
1143
+ Type *DestTy, const DataLayout &DL) {
1144
+ assert (Instruction::isCast (Opcode));
1145
+ switch (Opcode) {
1146
+ default :
1147
+ llvm_unreachable (" Missing case" );
1148
+ case Instruction::PtrToInt:
1149
+ // If the input is a inttoptr, eliminate the pair. This requires knowing
1150
+ // the width of a pointer, so it can't be done in ConstantExpr::getCast.
1151
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
1152
+ if (CE->getOpcode () == Instruction::IntToPtr) {
1153
+ Constant *Input = CE->getOperand (0 );
1154
+ unsigned InWidth = Input->getType ()->getScalarSizeInBits ();
1155
+ unsigned PtrWidth = DL.getPointerTypeSizeInBits (CE->getType ());
1156
+ if (PtrWidth < InWidth) {
1157
+ Constant *Mask =
1158
+ ConstantInt::get (CE->getContext (),
1159
+ APInt::getLowBitsSet (InWidth, PtrWidth));
1160
+ Input = ConstantExpr::getAnd (Input, Mask);
1161
+ }
1162
+ // Do a zext or trunc to get to the dest size.
1163
+ return ConstantExpr::getIntegerCast (Input, DestTy, false );
1164
+ }
1165
+ }
1166
+ return ConstantExpr::getCast (Opcode, C, DestTy);
1167
+ case Instruction::IntToPtr:
1168
+ // If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if
1169
+ // the int size is >= the ptr size and the address spaces are the same.
1170
+ // This requires knowing the width of a pointer, so it can't be done in
1171
+ // ConstantExpr::getCast.
1172
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
1173
+ if (CE->getOpcode () == Instruction::PtrToInt) {
1174
+ Constant *SrcPtr = CE->getOperand (0 );
1175
+ unsigned SrcPtrSize = DL.getPointerTypeSizeInBits (SrcPtr->getType ());
1176
+ unsigned MidIntSize = CE->getType ()->getScalarSizeInBits ();
1177
+
1178
+ if (MidIntSize >= SrcPtrSize) {
1179
+ unsigned SrcAS = SrcPtr->getType ()->getPointerAddressSpace ();
1180
+ if (SrcAS == DestTy->getPointerAddressSpace ())
1181
+ return FoldBitCast (CE->getOperand (0 ), DestTy, DL);
1182
+ }
1183
+ }
1184
+ }
1185
+
1186
+ return ConstantExpr::getCast (Opcode, C, DestTy);
1187
+ case Instruction::Trunc:
1188
+ case Instruction::ZExt:
1189
+ case Instruction::SExt:
1190
+ case Instruction::FPTrunc:
1191
+ case Instruction::FPExt:
1192
+ case Instruction::UIToFP:
1193
+ case Instruction::SIToFP:
1194
+ case Instruction::FPToUI:
1195
+ case Instruction::FPToSI:
1196
+ case Instruction::AddrSpaceCast:
1197
+ return ConstantExpr::getCast (Opcode, C, DestTy);
1198
+ case Instruction::BitCast:
1199
+ return FoldBitCast (C, DestTy, DL);
1200
+ }
1201
+ }
1202
+
1191
1203
// / Given a constant and a getelementptr constantexpr, return the constant value
1192
1204
// / being addressed by the constant expression, or null if something is funny
1193
1205
// / and we can't decide.
0 commit comments