|
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