|
57 | 57 | #include "llvm/IR/Intrinsics.h"
|
58 | 58 | #include "llvm/IR/IntrinsicsAArch64.h"
|
59 | 59 | #include "llvm/IR/IntrinsicsAMDGPU.h"
|
| 60 | +#include "llvm/IR/IntrinsicsEVM.h" |
60 | 61 | #include "llvm/IR/IntrinsicsRISCV.h"
|
61 | 62 | #include "llvm/IR/IntrinsicsX86.h"
|
62 | 63 | #include "llvm/IR/LLVMContext.h"
|
@@ -3740,6 +3741,28 @@ static unsigned computeNumSignBitsVectorConstant(const Value *V,
|
3740 | 3741 | return MinSignBits;
|
3741 | 3742 | }
|
3742 | 3743 |
|
| 3744 | +static unsigned computeNumSignBitsForEVMSignExtend(const IntrinsicInst *II) { |
| 3745 | + auto *Ty = dyn_cast<IntegerType>(II->getType()); |
| 3746 | + if (!Ty) |
| 3747 | + return 1; |
| 3748 | + |
| 3749 | + unsigned BitWidth = Ty->getIntegerBitWidth(); |
| 3750 | + if (BitWidth != 256) |
| 3751 | + return 1; |
| 3752 | + |
| 3753 | + const auto *ByteIdxC = dyn_cast<ConstantInt>(II->getArgOperand(0)); |
| 3754 | + if (!ByteIdxC) |
| 3755 | + return 1; |
| 3756 | + |
| 3757 | + // ByteIdx must be in range [0, 31]. |
| 3758 | + uint64_t ByteIdx = ByteIdxC->getZExtValue(); |
| 3759 | + if (ByteIdx >= BitWidth / 8) |
| 3760 | + return 1; |
| 3761 | + |
| 3762 | + unsigned Width = (ByteIdx + 1) * 8; |
| 3763 | + return BitWidth - Width + 1; |
| 3764 | +} |
| 3765 | + |
3743 | 3766 | static unsigned ComputeNumSignBitsImpl(const Value *V,
|
3744 | 3767 | const APInt &DemandedElts,
|
3745 | 3768 | unsigned Depth, const SimplifyQuery &Q);
|
@@ -4070,6 +4093,8 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
|
4070 | 4093 | switch (II->getIntrinsicID()) {
|
4071 | 4094 | default:
|
4072 | 4095 | break;
|
| 4096 | + case Intrinsic::evm_signextend: |
| 4097 | + return computeNumSignBitsForEVMSignExtend(II); |
4073 | 4098 | case Intrinsic::abs:
|
4074 | 4099 | Tmp =
|
4075 | 4100 | ComputeNumSignBits(U->getOperand(0), DemandedElts, Depth + 1, Q);
|
@@ -9509,10 +9534,35 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
|
9509 | 9534 | }
|
9510 | 9535 | }
|
9511 | 9536 |
|
| 9537 | +static ConstantRange getRangeForEVMSignExtend(const IntrinsicInst &II) { |
| 9538 | + unsigned BitWidth = II.getType()->getIntegerBitWidth(); |
| 9539 | + if (BitWidth != 256) |
| 9540 | + return ConstantRange::getFull(BitWidth); |
| 9541 | + |
| 9542 | + auto *ByteIdxC = dyn_cast<ConstantInt>(II.getArgOperand(0)); |
| 9543 | + if (!ByteIdxC) |
| 9544 | + return ConstantRange::getFull(BitWidth); |
| 9545 | + |
| 9546 | + // ByteIdx must be in range [0, 31]. |
| 9547 | + uint64_t ByteIdx = ByteIdxC->getZExtValue(); |
| 9548 | + if (ByteIdx >= BitWidth / 8) |
| 9549 | + return ConstantRange::getFull(BitWidth); |
| 9550 | + |
| 9551 | + // Range that signextend produces is: |
| 9552 | + // [ -2^(width-1), 2^(width-1)-1 ] in signed space |
| 9553 | + // Since ConstantRange is [Min, Max), and Max is exclusive, we need to add 1. |
| 9554 | + unsigned Width = (ByteIdx + 1) * 8; |
| 9555 | + return ConstantRange::getNonEmpty( |
| 9556 | + APInt::getSignedMinValue(Width).sext(BitWidth), |
| 9557 | + APInt::getSignedMaxValue(Width).sext(BitWidth) + 1); |
| 9558 | +} |
| 9559 | + |
9512 | 9560 | static ConstantRange getRangeForIntrinsic(const IntrinsicInst &II) {
|
9513 | 9561 | unsigned Width = II.getType()->getScalarSizeInBits();
|
9514 | 9562 | const APInt *C;
|
9515 | 9563 | switch (II.getIntrinsicID()) {
|
| 9564 | + case Intrinsic::evm_signextend: |
| 9565 | + return getRangeForEVMSignExtend(II); |
9516 | 9566 | case Intrinsic::ctpop:
|
9517 | 9567 | case Intrinsic::ctlz:
|
9518 | 9568 | case Intrinsic::cttz:
|
|
0 commit comments