Skip to content

Commit

Permalink
[IR] Remove zext and sext constant expressions (#71040)
Browse files Browse the repository at this point in the history
Remove support for zext and sext constant expressions. All places
creating them have been removed beforehand, so this just removes the
APIs and uses of these constant expressions in tests.

There is some additional cleanup that can be done on top of this, e.g.
we can remove the ZExtInst vs ZExtOperator footgun.

This is part of
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
  • Loading branch information
nikic authored Nov 3, 2023
1 parent e9db60c commit e4a4122
Show file tree
Hide file tree
Showing 62 changed files with 347 additions and 502 deletions.
8 changes: 0 additions & 8 deletions llvm/bindings/ocaml/llvm/llvm.ml
Original file line number Diff line number Diff line change
Expand Up @@ -661,8 +661,6 @@ external const_gep : lltype -> llvalue -> llvalue array -> llvalue
external const_in_bounds_gep : lltype -> llvalue -> llvalue array -> llvalue
= "llvm_const_in_bounds_gep"
external const_trunc : llvalue -> lltype -> llvalue = "llvm_const_trunc"
external const_sext : llvalue -> lltype -> llvalue = "llvm_const_sext"
external const_zext : llvalue -> lltype -> llvalue = "llvm_const_zext"
external const_fptrunc : llvalue -> lltype -> llvalue = "llvm_const_fptrunc"
external const_fpext : llvalue -> lltype -> llvalue = "llvm_const_fpext"
external const_uitofp : llvalue -> lltype -> llvalue = "llvm_const_uitofp"
Expand All @@ -672,16 +670,10 @@ external const_fptosi : llvalue -> lltype -> llvalue = "llvm_const_fptosi"
external const_ptrtoint : llvalue -> lltype -> llvalue = "llvm_const_ptrtoint"
external const_inttoptr : llvalue -> lltype -> llvalue = "llvm_const_inttoptr"
external const_bitcast : llvalue -> lltype -> llvalue = "llvm_const_bitcast"
external const_zext_or_bitcast : llvalue -> lltype -> llvalue
= "llvm_const_zext_or_bitcast"
external const_sext_or_bitcast : llvalue -> lltype -> llvalue
= "llvm_const_sext_or_bitcast"
external const_trunc_or_bitcast : llvalue -> lltype -> llvalue
= "llvm_const_trunc_or_bitcast"
external const_pointercast : llvalue -> lltype -> llvalue
= "llvm_const_pointercast"
external const_intcast : llvalue -> lltype -> is_signed:bool -> llvalue
= "llvm_const_intcast"
external const_fpcast : llvalue -> lltype -> llvalue = "llvm_const_fpcast"
external const_extractelement : llvalue -> llvalue -> llvalue
= "llvm_const_extractelement"
Expand Down
27 changes: 0 additions & 27 deletions llvm/bindings/ocaml/llvm/llvm.mli
Original file line number Diff line number Diff line change
Expand Up @@ -1171,16 +1171,6 @@ val const_in_bounds_gep : lltype -> llvalue -> llvalue array -> llvalue
See the method [llvm::ConstantExpr::getTrunc]. *)
val const_trunc : llvalue -> lltype -> llvalue

(** [const_sext c ty] returns the constant sign extension of integer constant
[c] to the larger integer type [ty].
See the method [llvm::ConstantExpr::getSExt]. *)
val const_sext : llvalue -> lltype -> llvalue

(** [const_zext c ty] returns the constant zero extension of integer constant
[c] to the larger integer type [ty].
See the method [llvm::ConstantExpr::getZExt]. *)
val const_zext : llvalue -> lltype -> llvalue

(** [const_fptrunc c ty] returns the constant truncation of floating point
constant [c] to the smaller floating point type [ty].
See the method [llvm::ConstantExpr::getFPTrunc]. *)
Expand Down Expand Up @@ -1226,16 +1216,6 @@ val const_inttoptr : llvalue -> lltype -> llvalue
See the method [llvm::ConstantExpr::getBitCast]. *)
val const_bitcast : llvalue -> lltype -> llvalue

(** [const_zext_or_bitcast c ty] returns a constant zext or bitwise cast
conversion of constant [c] to type [ty].
See the method [llvm::ConstantExpr::getZExtOrBitCast]. *)
val const_zext_or_bitcast : llvalue -> lltype -> llvalue

(** [const_sext_or_bitcast c ty] returns a constant sext or bitwise cast
conversion of constant [c] to type [ty].
See the method [llvm::ConstantExpr::getSExtOrBitCast]. *)
val const_sext_or_bitcast : llvalue -> lltype -> llvalue

(** [const_trunc_or_bitcast c ty] returns a constant trunc or bitwise cast
conversion of constant [c] to type [ty].
See the method [llvm::ConstantExpr::getTruncOrBitCast]. *)
Expand All @@ -1246,13 +1226,6 @@ val const_trunc_or_bitcast : llvalue -> lltype -> llvalue
See the method [llvm::ConstantExpr::getPointerCast]. *)
val const_pointercast : llvalue -> lltype -> llvalue

(** [const_intcast c ty ~is_signed] returns a constant sext/zext, bitcast,
or trunc for integer -> integer casts of constant [c] to type [ty].
When converting a narrower value to a wider one, whether sext or zext
will be used is controlled by [is_signed].
See the method [llvm::ConstantExpr::getIntegerCast]. *)
val const_intcast : llvalue -> lltype -> is_signed:bool -> llvalue

(** [const_fpcast c ty] returns a constant fpext, bitcast, or fptrunc for fp ->
fp casts of constant [c] to type [ty].
See the method [llvm::ConstantExpr::getFPCast]. *)
Expand Down
30 changes: 0 additions & 30 deletions llvm/bindings/ocaml/llvm/llvm_ocaml.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,18 +1271,6 @@ value llvm_const_trunc(value CV, value T) {
return to_val(Value);
}

/* llvalue -> lltype -> llvalue */
value llvm_const_sext(value CV, value T) {
LLVMValueRef Value = LLVMConstSExt(Value_val(CV), Type_val(T));
return to_val(Value);
}

/* llvalue -> lltype -> llvalue */
value llvm_const_zext(value CV, value T) {
LLVMValueRef Value = LLVMConstZExt(Value_val(CV), Type_val(T));
return to_val(Value);
}

/* llvalue -> lltype -> llvalue */
value llvm_const_fptrunc(value CV, value T) {
LLVMValueRef Value = LLVMConstFPTrunc(Value_val(CV), Type_val(T));
Expand Down Expand Up @@ -1337,18 +1325,6 @@ value llvm_const_bitcast(value CV, value T) {
return to_val(Value);
}

/* llvalue -> lltype -> llvalue */
value llvm_const_zext_or_bitcast(value CV, value T) {
LLVMValueRef Value = LLVMConstZExtOrBitCast(Value_val(CV), Type_val(T));
return to_val(Value);
}

/* llvalue -> lltype -> llvalue */
value llvm_const_sext_or_bitcast(value CV, value T) {
LLVMValueRef Value = LLVMConstSExtOrBitCast(Value_val(CV), Type_val(T));
return to_val(Value);
}

/* llvalue -> lltype -> llvalue */
value llvm_const_trunc_or_bitcast(value CV, value T) {
LLVMValueRef Value = LLVMConstTruncOrBitCast(Value_val(CV), Type_val(T));
Expand All @@ -1361,12 +1337,6 @@ value llvm_const_pointercast(value CV, value T) {
return to_val(Value);
}

/* llvalue -> lltype -> is_signed:bool -> llvalue */
value llvm_const_intcast(value CV, value T, value IsSigned) {
return to_val(
LLVMConstIntCast(Value_val(CV), Type_val(T), Bool_val(IsSigned)));
}

/* llvalue -> lltype -> llvalue */
value llvm_const_fpcast(value CV, value T) {
LLVMValueRef Value = LLVMConstFPCast(Value_val(CV), Type_val(T));
Expand Down
4 changes: 0 additions & 4 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4657,10 +4657,6 @@ The following is the syntax for constant expressions:

``trunc (CST to TYPE)``
Perform the :ref:`trunc operation <i_trunc>` on constants.
``zext (CST to TYPE)``
Perform the :ref:`zext operation <i_zext>` on constants.
``sext (CST to TYPE)``
Perform the :ref:`sext operation <i_sext>` on constants.
``fptrunc (CST to TYPE)``
Truncate a floating-point constant to another floating-point type.
The size of CST must be larger than the size of TYPE. Both types
Expand Down
7 changes: 7 additions & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Changes to the LLVM IR

* ``and``
* ``or``
* ``zext``
* ``sext``

* Added `llvm.exp10` intrinsic.

Expand Down Expand Up @@ -166,6 +168,11 @@ Changes to the C API

* ``LLVMConstAnd``
* ``LLVMConstOr``
* ``LLVMConstZExt``
* ``LLVMConstSExt``
* ``LLVMConstZExtOrBitCast``
* ``LLVMConstSExtOrBitCast``
* ``LLVMConstIntCast``

* Added ``LLVMCreateTargetMachineWithOptions``, along with helper functions for
an opaque option structure, as an alternative to ``LLVMCreateTargetMachine``.
Expand Down
8 changes: 0 additions & 8 deletions llvm/include/llvm-c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -2290,8 +2290,6 @@ LLVMValueRef LLVMConstInBoundsGEP2(LLVMTypeRef Ty, LLVMValueRef ConstantVal,
LLVMValueRef *ConstantIndices,
unsigned NumIndices);
LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
Expand All @@ -2302,16 +2300,10 @@ LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal,
LLVMTypeRef ToType);
LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal,
LLVMTypeRef ToType);
LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal,
LLVMTypeRef ToType);
LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal,
LLVMTypeRef ToType);
LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType,
LLVMBool isSigned);
LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant,
LLVMValueRef IndexConstant);
Expand Down
29 changes: 3 additions & 26 deletions llvm/include/llvm/IR/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -1041,8 +1041,6 @@ class ConstantExpr : public Constant {
static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false);
static Constant *getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced = false);
static Constant *getSExt(Constant *C, Type *Ty, bool OnlyIfReduced = false);
static Constant *getZExt(Constant *C, Type *Ty, bool OnlyIfReduced = false);
static Constant *getFPTrunc(Constant *C, Type *Ty,
bool OnlyIfReduced = false);
static Constant *getFPExtend(Constant *C, Type *Ty,
Expand Down Expand Up @@ -1140,29 +1138,12 @@ class ConstantExpr : public Constant {
static Constant *getCast(unsigned ops, Constant *C, Type *Ty,
bool OnlyIfReduced = false);

// Create a ZExt or BitCast cast constant expression
static Constant *
getZExtOrBitCast(Constant *C, ///< The constant to zext or bitcast
Type *Ty ///< The type to zext or bitcast C to
);

// Create a SExt or BitCast cast constant expression
static Constant *
getSExtOrBitCast(Constant *C, ///< The constant to sext or bitcast
Type *Ty ///< The type to sext or bitcast C to
);

// Create a Trunc or BitCast cast constant expression
static Constant *
getTruncOrBitCast(Constant *C, ///< The constant to trunc or bitcast
Type *Ty ///< The type to trunc or bitcast C to
);

/// Create either an sext, trunc or nothing, depending on whether Ty is
/// wider, narrower or the same as C->getType(). This only works with
/// integer or vector of integer types.
static Constant *getSExtOrTrunc(Constant *C, Type *Ty);

/// Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant
/// expression.
static Constant *
Expand All @@ -1177,13 +1158,6 @@ class ConstantExpr : public Constant {
Type *Ty ///< The type to bitcast or addrspacecast C to
);

/// Create a ZExt, Bitcast or Trunc for integer -> integer casts
static Constant *
getIntegerCast(Constant *C, ///< The integer constant to be casted
Type *Ty, ///< The integer type to cast to
bool IsSigned ///< Whether C should be treated as signed or not
);

/// Create a FPExt, Bitcast or FPTrunc for fp -> fp casts
static Constant *getFPCast(Constant *C, ///< The integer constant to be casted
Type *Ty ///< The integer type to cast to
Expand Down Expand Up @@ -1333,6 +1307,9 @@ class ConstantExpr : public Constant {
/// Whether creating a constant expression for this cast is desirable.
static bool isDesirableCastOp(unsigned Opcode);

/// Whether creating a constant expression for this cast is supported.
static bool isSupportedCastOp(unsigned Opcode);

/// Whether creating a constant expression for this getelementptr type is
/// supported.
static bool isSupportedGetElementPtr(const Type *SrcElemTy) {
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3805,8 +3805,6 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
}

case lltok::kw_trunc:
case lltok::kw_zext:
case lltok::kw_sext:
case lltok::kw_fptrunc:
case lltok::kw_fpext:
case lltok::kw_bitcast:
Expand Down Expand Up @@ -3866,6 +3864,10 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
return error(ID.Loc, "fneg constexprs are no longer supported");
case lltok::kw_select:
return error(ID.Loc, "select constexprs are no longer supported");
case lltok::kw_zext:
return error(ID.Loc, "zext constexprs are no longer supported");
case lltok::kw_sext:
return error(ID.Loc, "sext constexprs are no longer supported");
case lltok::kw_icmp:
case lltok::kw_fcmp: {
unsigned PredVal, Opc = Lex.getUIntVal();
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,9 @@ static bool isConstExprSupported(const BitcodeConstant *BC) {
if (Instruction::isBinaryOp(Opcode))
return ConstantExpr::isSupportedBinOp(Opcode);

if (Instruction::isCast(Opcode))
return ConstantExpr::isSupportedCastOp(Opcode);

if (Opcode == Instruction::GetElementPtr)
return ConstantExpr::isSupportedGetElementPtr(BC->SrcElemTy);

Expand Down
72 changes: 0 additions & 72 deletions llvm/lib/IR/ConstantFold.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,40 +258,6 @@ static Constant *ExtractConstantBytes(Constant *C, unsigned ByteStart,
// TODO: Handle the 'partially zero' case.
return nullptr;
}

case Instruction::ZExt: {
unsigned SrcBitSize =
cast<IntegerType>(CE->getOperand(0)->getType())->getBitWidth();

// If extracting something that is completely zero, return 0.
if (ByteStart*8 >= SrcBitSize)
return Constant::getNullValue(IntegerType::get(CE->getContext(),
ByteSize*8));

// If exactly extracting the input, return it.
if (ByteStart == 0 && ByteSize*8 == SrcBitSize)
return CE->getOperand(0);

// If extracting something completely in the input, if the input is a
// multiple of 8 bits, recurse.
if ((SrcBitSize&7) == 0 && (ByteStart+ByteSize)*8 <= SrcBitSize)
return ExtractConstantBytes(CE->getOperand(0), ByteStart, ByteSize);

// Otherwise, if extracting a subset of the input, which is not multiple of
// 8 bits, do a shift and trunc to get the bits.
if ((ByteStart+ByteSize)*8 < SrcBitSize) {
assert((SrcBitSize&7) && "Shouldn't get byte sized case here");
Constant *Res = CE->getOperand(0);
if (ByteStart)
Res = ConstantExpr::getLShr(Res,
ConstantInt::get(Res->getType(), ByteStart*8));
return ConstantExpr::getTrunc(Res, IntegerType::get(C->getContext(),
ByteSize*8));
}

// TODO: Handle the 'partially zero' case.
return nullptr;
}
}
}

Expand Down Expand Up @@ -986,16 +952,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
return C1; // X & -1 == X

if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
// (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
if (CE1->getOpcode() == Instruction::ZExt) {
unsigned DstWidth = CI2->getType()->getBitWidth();
unsigned SrcWidth =
CE1->getOperand(0)->getType()->getPrimitiveSizeInBits();
APInt PossiblySetBits(APInt::getLowBitsSet(DstWidth, SrcWidth));
if ((PossiblySetBits & CI2->getValue()) == PossiblySetBits)
return C1;
}

// If and'ing the address of a global with a constant, fold it.
if (CE1->getOpcode() == Instruction::PtrToInt &&
isa<GlobalValue>(CE1->getOperand(0))) {
Expand Down Expand Up @@ -1056,12 +1012,6 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
}
}
break;
case Instruction::AShr:
// ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1))
if (CE1->getOpcode() == Instruction::ZExt) // Top bits known zero.
return ConstantExpr::getLShr(C1, C2);
break;
}
} else if (isa<ConstantInt>(C1)) {
// If C1 is a ConstantInt and C2 is not, swap the operands.
Expand Down Expand Up @@ -1461,17 +1411,13 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
[[fallthrough]];
case Instruction::UIToFP:
case Instruction::SIToFP:
case Instruction::ZExt:
case Instruction::SExt:
// We can't evaluate floating point casts or truncations.
if (CE1Op0->getType()->isFPOrFPVectorTy())
break;

// If the cast is not actually changing bits, and the second operand is a
// null pointer, do the comparison with the pre-casted value.
if (V2->isNullValue() && CE1->getType()->isIntOrPtrTy()) {
if (CE1->getOpcode() == Instruction::ZExt) isSigned = false;
if (CE1->getOpcode() == Instruction::SExt) isSigned = true;
return evaluateICmpRelation(CE1Op0,
Constant::getNullValue(CE1Op0->getType()),
isSigned);
Expand Down Expand Up @@ -1828,24 +1774,6 @@ Constant *llvm::ConstantFoldCompareInstruction(CmpInst::Predicate Predicate,
}
}

// If the left hand side is an extension, try eliminating it.
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
if ((CE1->getOpcode() == Instruction::SExt &&
ICmpInst::isSigned(Predicate)) ||
(CE1->getOpcode() == Instruction::ZExt &&
!ICmpInst::isSigned(Predicate))) {
Constant *CE1Op0 = CE1->getOperand(0);
Constant *CE1Inverse = ConstantExpr::getTrunc(CE1, CE1Op0->getType());
if (CE1Inverse == CE1Op0) {
// Check whether we can safely truncate the right hand side.
Constant *C2Inverse = ConstantExpr::getTrunc(C2, CE1Op0->getType());
if (ConstantExpr::getCast(CE1->getOpcode(), C2Inverse,
C2->getType()) == C2)
return ConstantExpr::getICmp(Predicate, CE1Inverse, C2Inverse);
}
}
}

if ((!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) ||
(C1->isNullValue() && !C2->isNullValue())) {
// If C2 is a constant expr and C1 isn't, flip them around and fold the
Expand Down
Loading

0 comments on commit e4a4122

Please sign in to comment.