2727#include " llvm/IR/InstrTypes.h"
2828#include " llvm/IR/Instruction.h"
2929#include " llvm/IR/Intrinsics.h"
30+ #include " llvm/IR/IntrinsicsEVM.h"
3031#include " llvm/IR/Metadata.h"
3132#include " llvm/IR/Operator.h"
3233#include " llvm/Support/Compiler.h"
@@ -1009,6 +1010,7 @@ bool ConstantRange::isIntrinsicSupported(Intrinsic::ID IntrinsicID) {
10091010 case Intrinsic::ctlz:
10101011 case Intrinsic::cttz:
10111012 case Intrinsic::ctpop:
1013+ case Intrinsic::evm_signextend:
10121014 return true ;
10131015 default :
10141016 return false ;
@@ -1018,6 +1020,8 @@ bool ConstantRange::isIntrinsicSupported(Intrinsic::ID IntrinsicID) {
10181020ConstantRange ConstantRange::intrinsic (Intrinsic::ID IntrinsicID,
10191021 ArrayRef<ConstantRange> Ops) {
10201022 switch (IntrinsicID) {
1023+ case Intrinsic::evm_signextend:
1024+ return Ops[0 ].evmSignExtend (Ops[1 ]);
10211025 case Intrinsic::uadd_sat:
10221026 return Ops[0 ].uadd_sat (Ops[1 ]);
10231027 case Intrinsic::usub_sat:
@@ -1953,6 +1957,26 @@ ConstantRange ConstantRange::ctpop() const {
19531957 return CR1.unionWith (CR2);
19541958}
19551959
1960+ ConstantRange ConstantRange::evmSignExtend (const ConstantRange &Other) const {
1961+ unsigned BitWidth = getBitWidth ();
1962+ if (BitWidth != 256 )
1963+ return getFull ();
1964+
1965+ if (isEmptySet () || Other.isEmptySet ())
1966+ return getEmpty ();
1967+
1968+ if (!isSingleElement ())
1969+ return getFull ();
1970+
1971+ // ByteIdx must be in range [0, 31].
1972+ uint64_t ByteIdx = getSingleElement ()->getZExtValue ();
1973+ if (ByteIdx >= BitWidth / 8 )
1974+ return getFull ();
1975+
1976+ unsigned Width = (ByteIdx + 1 ) * 8 ;
1977+ return Other.truncate (Width).signExtend (BitWidth);
1978+ }
1979+
19561980ConstantRange::OverflowResult ConstantRange::unsignedAddMayOverflow (
19571981 const ConstantRange &Other) const {
19581982 if (isEmptySet () || Other.isEmptySet ())
0 commit comments