@@ -448,30 +448,35 @@ ConstExprFunctionState::computeConstantValueBuiltin(BuiltinInst *inst) {
448
448
if (operand.getKind () != SymbolicValue::Integer)
449
449
return unknownResult ();
450
450
451
- auto operandVal = operand.getIntegerValue ();
451
+ APInt operandVal = operand.getIntegerValue ();
452
452
uint32_t srcBitWidth = operandVal.getBitWidth ();
453
453
auto dstBitWidth =
454
454
builtin.Types [1 ]->castTo <BuiltinIntegerType>()->getGreatestWidth ();
455
455
456
- APInt result = operandVal.trunc (dstBitWidth);
456
+ // Note that the if the source type is a Builtin.IntLiteral, operandVal
457
+ // could have fewer bits than the destination bit width and may only
458
+ // require a sign extension.
459
+ APInt result = operandVal.sextOrTrunc (dstBitWidth);
457
460
458
- // Compute the overflow by re-extending the value back to its source and
459
- // checking for loss of value.
460
- APInt reextended =
461
- dstSigned ? result.sext (srcBitWidth) : result.zext (srcBitWidth);
462
- bool overflowed = (operandVal != reextended);
461
+ // Determine if there is a overflow.
462
+ if (operandVal.getBitWidth () > dstBitWidth) {
463
+ // Re-extend the value back to its source and check for loss of value.
464
+ APInt reextended =
465
+ dstSigned ? result.sext (srcBitWidth) : result.zext (srcBitWidth);
466
+ bool overflowed = (operandVal != reextended);
463
467
464
- if (!srcSigned && dstSigned)
465
- overflowed |= result.isSignBitSet ();
468
+ if (!srcSigned && dstSigned)
469
+ overflowed |= result.isSignBitSet ();
466
470
467
- if (overflowed)
468
- return evaluator.getUnknown (SILValue (inst), UnknownReason::Overflow);
471
+ if (overflowed)
472
+ return evaluator.getUnknown (SILValue (inst), UnknownReason::Overflow);
473
+ }
469
474
470
475
auto &allocator = evaluator.getAllocator ();
471
476
// Build the Symbolic value result for our truncated value.
472
477
return SymbolicValue::getAggregate (
473
478
{SymbolicValue::getInteger (result, allocator),
474
- SymbolicValue::getInteger (APInt (1 , overflowed ), allocator)},
479
+ SymbolicValue::getInteger (APInt (1 , false ), allocator)},
475
480
allocator);
476
481
};
477
482
0 commit comments