Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IR] Remove zext and sext constant expressions #71040

Merged
merged 2 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:
Copy link
Collaborator

@nhaehnle nhaehnle Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code puzzles me. Not so much your change to it, but...

The method is called evaluateICmpRelation, and a whole lot of comments talk about how we can't evaluate floating point values. So how can we ever get the UIToFP or SIToFP cases here? That seems like it would require a floating point operand to an icmp...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this doesn't make sense. I'll clean it up in a followup change.

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
Loading