@@ -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 );
@@ -1367,13 +1373,30 @@ Constant *llvm::ConstantFoldFPInstOperands(unsigned Opcode, Constant *LHS,
1367
1373
if (!Op1)
1368
1374
return nullptr ;
1369
1375
1376
+ // If nsz or an algebraic FMF flag is set, the result of the FP operation
1377
+ // may change due to future optimization. Don't constant fold them if
1378
+ // non-deterministic results are not allowed.
1379
+ if (!AllowNonDeterministic)
1380
+ if (auto *FP = dyn_cast_or_null<FPMathOperator>(I))
1381
+ if (FP->hasNoSignedZeros () || FP->hasAllowReassoc () ||
1382
+ FP->hasAllowContract () || FP->hasAllowReciprocal ())
1383
+ return nullptr ;
1384
+
1370
1385
// Calculate constant result.
1371
1386
Constant *C = ConstantFoldBinaryOpOperands (Opcode, Op0, Op1, DL);
1372
1387
if (!C)
1373
1388
return nullptr ;
1374
1389
1375
1390
// Flush denormal output if needed.
1376
- return FlushFPConstant (C, I, /* IsOutput */ true );
1391
+ C = FlushFPConstant (C, I, /* IsOutput */ true );
1392
+ if (!C)
1393
+ return nullptr ;
1394
+
1395
+ // The precise NaN value is non-deterministic.
1396
+ if (!AllowNonDeterministic && C->isNaN ())
1397
+ return nullptr ;
1398
+
1399
+ return C;
1377
1400
}
1378
1401
// If instruction lacks a parent/function and the denormal mode cannot be
1379
1402
// determined, use the default (IEEE).
@@ -3401,7 +3424,8 @@ Constant *llvm::ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS,
3401
3424
3402
3425
Constant *llvm::ConstantFoldCall (const CallBase *Call, Function *F,
3403
3426
ArrayRef<Constant *> Operands,
3404
- const TargetLibraryInfo *TLI) {
3427
+ const TargetLibraryInfo *TLI,
3428
+ bool AllowNonDeterministic) {
3405
3429
if (Call->isNoBuiltin ())
3406
3430
return nullptr ;
3407
3431
if (!F->hasName ())
@@ -3417,8 +3441,13 @@ Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F,
3417
3441
return nullptr ;
3418
3442
}
3419
3443
3420
- StringRef Name = F->getName ();
3444
+ // Conservatively assume that floating-point libcalls may be
3445
+ // non-deterministic.
3421
3446
Type *Ty = F->getReturnType ();
3447
+ if (!AllowNonDeterministic && Ty->isFPOrFPVectorTy ())
3448
+ return nullptr ;
3449
+
3450
+ StringRef Name = F->getName ();
3422
3451
if (auto *FVTy = dyn_cast<FixedVectorType>(Ty))
3423
3452
return ConstantFoldFixedVectorCall (
3424
3453
Name, IID, FVTy, Operands, F->getParent ()->getDataLayout (), TLI, Call);
0 commit comments