@@ -992,7 +992,8 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
992
992
Constant *ConstantFoldInstOperandsImpl (const Value *InstOrCE, unsigned Opcode,
993
993
ArrayRef<Constant *> Ops,
994
994
const DataLayout &DL,
995
- const TargetLibraryInfo *TLI) {
995
+ const TargetLibraryInfo *TLI,
996
+ bool AllowNonDeterministic) {
996
997
Type *DestTy = InstOrCE->getType ();
997
998
998
999
if (Instruction::isUnaryOp (Opcode))
@@ -1011,7 +1012,8 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode,
1011
1012
// TODO: If a constant expression is being folded rather than an
1012
1013
// instruction, denormals will not be flushed/treated as zero
1013
1014
if (const auto *I = dyn_cast<Instruction>(InstOrCE)) {
1014
- return ConstantFoldFPInstOperands (Opcode, Ops[0 ], Ops[1 ], DL, I);
1015
+ return ConstantFoldFPInstOperands (Opcode, Ops[0 ], Ops[1 ], DL, I,
1016
+ AllowNonDeterministic);
1015
1017
}
1016
1018
}
1017
1019
return ConstantFoldBinaryOpOperands (Opcode, Ops[0 ], Ops[1 ], DL);
@@ -1053,7 +1055,8 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode,
1053
1055
if (auto *F = dyn_cast<Function>(Ops.back ())) {
1054
1056
const auto *Call = cast<CallBase>(InstOrCE);
1055
1057
if (canConstantFoldCallTo (Call, F))
1056
- return ConstantFoldCall (Call, F, Ops.slice (0 , Ops.size () - 1 ), TLI);
1058
+ return ConstantFoldCall (Call, F, Ops.slice (0 , Ops.size () - 1 ), TLI,
1059
+ AllowNonDeterministic);
1057
1060
}
1058
1061
return nullptr ;
1059
1062
case Instruction::Select:
@@ -1114,8 +1117,8 @@ ConstantFoldConstantImpl(const Constant *C, const DataLayout &DL,
1114
1117
}
1115
1118
1116
1119
if (auto *CE = dyn_cast<ConstantExpr>(C)) {
1117
- if (Constant *Res =
1118
- ConstantFoldInstOperandsImpl ( CE, CE->getOpcode (), Ops, DL, TLI))
1120
+ if (Constant *Res = ConstantFoldInstOperandsImpl (
1121
+ CE, CE->getOpcode (), Ops, DL, TLI, /* AllowNonDeterministic= */ true ))
1119
1122
return Res;
1120
1123
return const_cast <Constant *>(C);
1121
1124
}
@@ -1183,8 +1186,10 @@ Constant *llvm::ConstantFoldConstant(const Constant *C, const DataLayout &DL,
1183
1186
Constant *llvm::ConstantFoldInstOperands (Instruction *I,
1184
1187
ArrayRef<Constant *> Ops,
1185
1188
const DataLayout &DL,
1186
- const TargetLibraryInfo *TLI) {
1187
- return ConstantFoldInstOperandsImpl (I, I->getOpcode (), Ops, DL, TLI);
1189
+ const TargetLibraryInfo *TLI,
1190
+ bool AllowNonDeterministic) {
1191
+ return ConstantFoldInstOperandsImpl (I, I->getOpcode (), Ops, DL, TLI,
1192
+ AllowNonDeterministic);
1188
1193
}
1189
1194
1190
1195
Constant *llvm::ConstantFoldCompareInstOperands (
@@ -1357,7 +1362,8 @@ Constant *llvm::FlushFPConstant(Constant *Operand, const Instruction *I,
1357
1362
1358
1363
Constant *llvm::ConstantFoldFPInstOperands (unsigned Opcode, Constant *LHS,
1359
1364
Constant *RHS, const DataLayout &DL,
1360
- const Instruction *I) {
1365
+ const Instruction *I,
1366
+ bool AllowNonDeterministic) {
1361
1367
if (Instruction::isBinaryOp (Opcode)) {
1362
1368
// Flush denormal inputs if needed.
1363
1369
Constant *Op0 = FlushFPConstant (LHS, I, /* IsOutput */ false );
@@ -1373,7 +1379,15 @@ Constant *llvm::ConstantFoldFPInstOperands(unsigned Opcode, Constant *LHS,
1373
1379
return nullptr ;
1374
1380
1375
1381
// Flush denormal output if needed.
1376
- return FlushFPConstant (C, I, /* IsOutput */ true );
1382
+ C = FlushFPConstant (C, I, /* IsOutput */ true );
1383
+ if (!C)
1384
+ return nullptr ;
1385
+
1386
+ // The precise NaN value is non-deterministic.
1387
+ if (!AllowNonDeterministic && C->isNaN ())
1388
+ return nullptr ;
1389
+
1390
+ return C;
1377
1391
}
1378
1392
// If instruction lacks a parent/function and the denormal mode cannot be
1379
1393
// determined, use the default (IEEE).
@@ -3401,7 +3415,8 @@ Constant *llvm::ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS,
3401
3415
3402
3416
Constant *llvm::ConstantFoldCall (const CallBase *Call, Function *F,
3403
3417
ArrayRef<Constant *> Operands,
3404
- const TargetLibraryInfo *TLI) {
3418
+ const TargetLibraryInfo *TLI,
3419
+ bool AllowNonDeterministic) {
3405
3420
if (Call->isNoBuiltin ())
3406
3421
return nullptr ;
3407
3422
if (!F->hasName ())
@@ -3417,8 +3432,13 @@ Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F,
3417
3432
return nullptr ;
3418
3433
}
3419
3434
3420
- StringRef Name = F->getName ();
3435
+ // Conservatively assume that floating-point libcalls may be
3436
+ // non-deterministic.
3421
3437
Type *Ty = F->getReturnType ();
3438
+ if (!AllowNonDeterministic && Ty->isFPOrFPVectorTy ())
3439
+ return nullptr ;
3440
+
3441
+ StringRef Name = F->getName ();
3422
3442
if (auto *FVTy = dyn_cast<FixedVectorType>(Ty))
3423
3443
return ConstantFoldFixedVectorCall (
3424
3444
Name, IID, FVTy, Operands, F->getParent ()->getDataLayout (), TLI, Call);
0 commit comments