Skip to content

Commit

Permalink
[ConstExpr] Remove select constant expression
Browse files Browse the repository at this point in the history
This removes the select constant expression, as part of
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
Uses of this expressions have already been removed in advance,
so this just removes related infrastructure and updates tests.

Differential Revision: https://reviews.llvm.org/D145382
  • Loading branch information
nikic committed Mar 16, 2023
1 parent b293c62 commit bbfb13a
Show file tree
Hide file tree
Showing 38 changed files with 108 additions and 307 deletions.
2 changes: 0 additions & 2 deletions llvm/bindings/ocaml/llvm/llvm.ml
Expand Up @@ -685,8 +685,6 @@ external const_pointercast : llvalue -> lltype -> llvalue
external const_intcast : llvalue -> lltype -> is_signed:bool -> llvalue
= "llvm_const_intcast"
external const_fpcast : llvalue -> lltype -> llvalue = "llvm_const_fpcast"
external const_select : llvalue -> llvalue -> llvalue -> llvalue
= "llvm_const_select"
external const_extractelement : llvalue -> llvalue -> llvalue
= "llvm_const_extractelement"
external const_insertelement : llvalue -> llvalue -> llvalue -> llvalue
Expand Down
5 changes: 0 additions & 5 deletions llvm/bindings/ocaml/llvm/llvm.mli
Expand Up @@ -1268,11 +1268,6 @@ val const_intcast : llvalue -> lltype -> is_signed:bool -> llvalue
See the method [llvm::ConstantExpr::getFPCast]. *)
val const_fpcast : llvalue -> lltype -> llvalue

(** [const_select cond t f] returns the constant conditional which returns value
[t] if the boolean constant [cond] is true and the value [f] otherwise.
See the method [llvm::ConstantExpr::getSelect]. *)
val const_select : llvalue -> llvalue -> llvalue -> llvalue

(** [const_extractelement vec i] returns the constant [i]th element of
constant vector [vec]. [i] must be a constant [i32] value unsigned less than
the size of the vector.
Expand Down
7 changes: 0 additions & 7 deletions llvm/bindings/ocaml/llvm/llvm_ocaml.c
Expand Up @@ -1385,13 +1385,6 @@ value llvm_const_fpcast(value CV, value T) {
return to_val(Value);
}

/* llvalue -> llvalue -> llvalue -> llvalue */
value llvm_const_select(value Cond, value IfTrue, value IfFalse) {
LLVMValueRef Value =
LLVMConstSelect(Value_val(Cond), Value_val(IfTrue), Value_val(IfFalse));
return to_val(Value);
}

/* llvalue -> llvalue -> llvalue */
value llvm_const_extractelement(value V, value I) {
LLVMValueRef Value = LLVMConstExtractElement(Value_val(V), Value_val(I));
Expand Down
11 changes: 11 additions & 0 deletions llvm/docs/ReleaseNotes.rst
Expand Up @@ -56,6 +56,11 @@ Changes to the LLVM IR
* The ``nofpclass`` attribute was introduced. This allows more
optimizations around special floating point value comparisons.

* The constant expression variants of the following instructions have been
removed:

* ``select``

Changes to building LLVM
------------------------

Expand Down Expand Up @@ -151,6 +156,12 @@ Changes to the C API
These belonged to the no longer supported legacy pass manager.
* As part of the opaque pointer transition, ``LLVMGetElementType`` no longer
gives the pointee type of a pointer type.
* The following functions for creating constant expressions have been removed,
because the underlying constant expressions are no longer supported. Instead,
an instruction should be created using the ``LLVMBuildXYZ`` APIs, which will
constant fold the operands if possible and create an instruction otherwise:

* ``LLVMConstSelect``

Changes to the FastISel infrastructure
--------------------------------------
Expand Down
3 changes: 0 additions & 3 deletions llvm/include/llvm-c/Core.h
Expand Up @@ -2257,9 +2257,6 @@ LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal,
LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType,
LLVMBool isSigned);
LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition,
LLVMValueRef ConstantIfTrue,
LLVMValueRef ConstantIfFalse);
LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant,
LLVMValueRef IndexConstant);
LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant,
Expand Down
6 changes: 0 additions & 6 deletions llvm/include/llvm/IR/Constants.h
Expand Up @@ -1208,12 +1208,6 @@ class ConstantExpr : public Constant {
/// Return true if this is a compare constant expression
bool isCompare() const;

/// Select constant expr
///
/// \param OnlyIfReducedTy see \a getWithOperands() docs.
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2,
Type *OnlyIfReducedTy = nullptr);

/// get - Return a binary or shift operator constant expression,
/// folding if possible.
///
Expand Down
12 changes: 3 additions & 9 deletions llvm/lib/AsmParser/LLParser.cpp
Expand Up @@ -3882,6 +3882,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
return error(ID.Loc, "frem constexprs are no longer supported");
case lltok::kw_fneg:
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_icmp:
case lltok::kw_fcmp: {
unsigned PredVal, Opc = Lex.getUIntVal();
Expand Down Expand Up @@ -4011,8 +4013,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
case lltok::kw_getelementptr:
case lltok::kw_shufflevector:
case lltok::kw_insertelement:
case lltok::kw_extractelement:
case lltok::kw_select: {
case lltok::kw_extractelement: {
unsigned Opc = Lex.getUIntVal();
SmallVector<Constant*, 16> Elts;
bool InBounds = false;
Expand Down Expand Up @@ -4091,13 +4092,6 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {

ID.ConstantVal = ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices,
InBounds, InRangeOp);
} else if (Opc == Instruction::Select) {
if (Elts.size() != 3)
return error(ID.Loc, "expected three operands to select");
if (const char *Reason = SelectInst::areInvalidOperands(Elts[0], Elts[1],
Elts[2]))
return error(ID.Loc, Reason);
ID.ConstantVal = ConstantExpr::getSelect(Elts[0], Elts[1], Elts[2]);
} else if (Opc == Instruction::ShuffleVector) {
if (Elts.size() != 3)
return error(ID.Loc, "expected three operands to shufflevector");
Expand Down
11 changes: 7 additions & 4 deletions llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Expand Up @@ -1417,7 +1417,13 @@ static bool isConstExprSupported(const BitcodeConstant *BC) {
if (Opcode == Instruction::GetElementPtr)
return ConstantExpr::isSupportedGetElementPtr(BC->SrcElemTy);

return Opcode != Instruction::FNeg;
switch (Opcode) {
case Instruction::FNeg:
case Instruction::Select:
return false;
default:
return true;
}
}

Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
Expand Down Expand Up @@ -1549,9 +1555,6 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
ArrayRef(ConstOps).drop_front(),
BC->Flags, BC->getInRangeIndex());
break;
case Instruction::Select:
C = ConstantExpr::getSelect(ConstOps[0], ConstOps[1], ConstOps[2]);
break;
case Instruction::ExtractElement:
C = ConstantExpr::getExtractElement(ConstOps[0], ConstOps[1]);
break;
Expand Down
6 changes: 0 additions & 6 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Expand Up @@ -2676,12 +2676,6 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal,
}
break;
}
case Instruction::Select:
Code = bitc::CST_CODE_CE_SELECT;
Record.push_back(VE.getValueID(C->getOperand(0)));
Record.push_back(VE.getValueID(C->getOperand(1)));
Record.push_back(VE.getValueID(C->getOperand(2)));
break;
case Instruction::ExtractElement:
Code = bitc::CST_CODE_CE_EXTRACTELT;
Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
Expand Down
11 changes: 0 additions & 11 deletions llvm/lib/IR/ConstantFold.cpp
Expand Up @@ -593,17 +593,6 @@ Constant *llvm::ConstantFoldSelectInstruction(Constant *Cond,
if (isa<UndefValue>(V1) && NotPoison(V2)) return V2;
if (isa<UndefValue>(V2) && NotPoison(V1)) return V1;

if (ConstantExpr *TrueVal = dyn_cast<ConstantExpr>(V1)) {
if (TrueVal->getOpcode() == Instruction::Select)
if (TrueVal->getOperand(0) == Cond)
return ConstantExpr::getSelect(Cond, TrueVal->getOperand(1), V2);
}
if (ConstantExpr *FalseVal = dyn_cast<ConstantExpr>(V2)) {
if (FalseVal->getOpcode() == Instruction::Select)
if (FalseVal->getOperand(0) == Cond)
return ConstantExpr::getSelect(Cond, V1, FalseVal->getOperand(2));
}

return nullptr;
}

Expand Down
23 changes: 0 additions & 23 deletions llvm/lib/IR/Constants.cpp
Expand Up @@ -547,8 +547,6 @@ void llvm::deleteConstant(Constant *C) {
delete static_cast<CastConstantExpr *>(C);
else if (isa<BinaryConstantExpr>(C))
delete static_cast<BinaryConstantExpr *>(C);
else if (isa<SelectConstantExpr>(C))
delete static_cast<SelectConstantExpr *>(C);
else if (isa<ExtractElementConstantExpr>(C))
delete static_cast<ExtractElementConstantExpr *>(C);
else if (isa<InsertElementConstantExpr>(C))
Expand Down Expand Up @@ -1488,8 +1486,6 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
case Instruction::BitCast:
case Instruction::AddrSpaceCast:
return ConstantExpr::getCast(getOpcode(), Ops[0], Ty, OnlyIfReduced);
case Instruction::Select:
return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2], OnlyIfReducedTy);
case Instruction::InsertElement:
return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2],
OnlyIfReducedTy);
Expand Down Expand Up @@ -2441,23 +2437,6 @@ Constant *ConstantExpr::getCompare(unsigned short Predicate, Constant *C1,
}
}

Constant *ConstantExpr::getSelect(Constant *C, Constant *V1, Constant *V2,
Type *OnlyIfReducedTy) {
assert(!SelectInst::areInvalidOperands(C, V1, V2)&&"Invalid select operands");

if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2))
return SC; // Fold common cases

if (OnlyIfReducedTy == V1->getType())
return nullptr;

Constant *ArgVec[] = { C, V1, V2 };
ConstantExprKeyType Key(Instruction::Select, ArgVec);

LLVMContextImpl *pImpl = C->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(V1->getType(), Key);
}

Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
ArrayRef<Value *> Idxs, bool InBounds,
std::optional<unsigned> InRangeIndex,
Expand Down Expand Up @@ -3439,8 +3418,6 @@ Instruction *ConstantExpr::getAsInstruction(Instruction *InsertBefore) const {
case Instruction::AddrSpaceCast:
return CastInst::Create((Instruction::CastOps)getOpcode(), Ops[0],
getType(), "", InsertBefore);
case Instruction::Select:
return SelectInst::Create(Ops[0], Ops[1], Ops[2], "", InsertBefore);
case Instruction::InsertElement:
return InsertElementInst::Create(Ops[0], Ops[1], Ops[2], "", InsertBefore);
case Instruction::ExtractElement:
Expand Down
33 changes: 0 additions & 33 deletions llvm/lib/IR/ConstantsContext.h
Expand Up @@ -90,32 +90,6 @@ class BinaryConstantExpr final : public ConstantExpr {
}
};

/// SelectConstantExpr - This class is private to Constants.cpp, and is used
/// behind the scenes to implement select constant exprs.
class SelectConstantExpr final : public ConstantExpr {
public:
SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
: ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
Op<0>() = C1;
Op<1>() = C2;
Op<2>() = C3;
}

// allocate space for exactly three operands
void *operator new(size_t S) { return User::operator new(S, 3); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }

/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);

static bool classof(const ConstantExpr *CE) {
return CE->getOpcode() == Instruction::Select;
}
static bool classof(const Value *V) {
return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
}
};

/// ExtractElementConstantExpr - This class is private to
/// Constants.cpp, and is used behind the scenes to implement
/// extractelement constant exprs.
Expand Down Expand Up @@ -279,11 +253,6 @@ struct OperandTraits<BinaryConstantExpr>
: public FixedNumOperandTraits<BinaryConstantExpr, 2> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)

template <>
struct OperandTraits<SelectConstantExpr>
: public FixedNumOperandTraits<SelectConstantExpr, 3> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)

template <>
struct OperandTraits<ExtractElementConstantExpr>
: public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {};
Expand Down Expand Up @@ -523,8 +492,6 @@ struct ConstantExprKeyType {
return new BinaryConstantExpr(Opcode, Ops[0], Ops[1],
SubclassOptionalData);
llvm_unreachable("Invalid ConstantExpr!");
case Instruction::Select:
return new SelectConstantExpr(Ops[0], Ops[1], Ops[2]);
case Instruction::ExtractElement:
return new ExtractElementConstantExpr(Ops[0], Ops[1]);
case Instruction::InsertElement:
Expand Down
8 changes: 0 additions & 8 deletions llvm/lib/IR/Core.cpp
Expand Up @@ -1799,14 +1799,6 @@ LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) {
unwrap(ToType)));
}

LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition,
LLVMValueRef ConstantIfTrue,
LLVMValueRef ConstantIfFalse) {
return wrap(ConstantExpr::getSelect(unwrap<Constant>(ConstantCondition),
unwrap<Constant>(ConstantIfTrue),
unwrap<Constant>(ConstantIfFalse)));
}

LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant,
LLVMValueRef IndexConstant) {
return wrap(ConstantExpr::getExtractElement(unwrap<Constant>(VectorConstant),
Expand Down
12 changes: 0 additions & 12 deletions llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp
Expand Up @@ -694,18 +694,6 @@ static Value *cloneConstantExprWithNewAddressSpace(
return ConstantExpr::getAddrSpaceCast(CE, TargetType);
}

if (CE->getOpcode() == Instruction::Select) {
Constant *Src0 = CE->getOperand(1);
Constant *Src1 = CE->getOperand(2);
if (Src0->getType()->getPointerAddressSpace() ==
Src1->getType()->getPointerAddressSpace()) {

return ConstantExpr::getSelect(
CE->getOperand(0), ConstantExpr::getAddrSpaceCast(Src0, TargetType),
ConstantExpr::getAddrSpaceCast(Src1, TargetType));
}
}

if (CE->getOpcode() == Instruction::IntToPtr) {
assert(isNoopPtrIntCastPair(cast<Operator>(CE), *DL, TTI));
Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
Expand Down
7 changes: 5 additions & 2 deletions llvm/test/Analysis/ScalarEvolution/logical-operations.ll
Expand Up @@ -410,11 +410,14 @@ define ptr @select_between_constantptrs(i1 %c, ptr %x) {
define ptr @tautological_select() {
; CHECK-LABEL: 'tautological_select'
; CHECK-NEXT: Classifying expressions for: @tautological_select
; CHECK-NEXT: %r = getelementptr i8, ptr @constant, i32 0
; CHECK-NEXT: %s = select i1 true, ptr @constant, ptr @another_constant
; CHECK-NEXT: --> @constant U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: %r = getelementptr i8, ptr %s
; CHECK-NEXT: --> @constant U: [0,-3) S: [-9223372036854775808,9223372036854775805)
; CHECK-NEXT: Determining loop execution counts for: @tautological_select
;
%r = getelementptr i8, ptr select (i1 true, ptr @constant, ptr @another_constant), i32 0
%s = select i1 true, ptr @constant, ptr @another_constant
%r = getelementptr i8, ptr %s
ret ptr %r
}

Expand Down
8 changes: 4 additions & 4 deletions llvm/test/Assembler/ConstantExprFoldSelect.ll
@@ -1,9 +1,9 @@
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
; RUN: verify-uselistorder %s
; PR18319

define void @function() {
%c = trunc <4 x i16> select (<4 x i1> <i1 undef, i1 undef, i1 false, i1 true>, <4 x i16> <i16 undef, i16 2, i16 3, i16 4>, <4 x i16> <i16 -1, i16 -2, i16 -3, i16 -4>) to <4 x i8>
define <4 x i16> @function() {
%s = select <4 x i1> <i1 undef, i1 undef, i1 false, i1 true>, <4 x i16> <i16 undef, i16 2, i16 3, i16 4>, <4 x i16> <i16 -1, i16 -2, i16 -3, i16 -4>
; CHECK: <i16 undef, i16 -2, i16 -3, i16 4>
ret void
ret <4 x i16> %s
}
5 changes: 0 additions & 5 deletions llvm/test/Bindings/OCaml/core.ml
Expand Up @@ -333,18 +333,13 @@ let test_constants () =
group "misc constants";
(* CHECK: const_size_of{{.*}}getelementptr{{.*}}null
* CHECK: const_gep{{.*}}getelementptr
* CHECK: const_select{{.*}}select
* CHECK: const_extractelement{{.*}}extractelement
* CHECK: const_insertelement{{.*}}insertelement
* CHECK: const_shufflevector = global <4 x i32> <i32 0, i32 1, i32 1, i32 0>
*)
ignore (define_global "const_size_of" (size_of (pointer_type context)) m);
ignore (define_global "const_gep" (const_gep i8_type foldbomb_gv [| five |])
m);
ignore (define_global "const_select" (const_select
(const_icmp Icmp.Sle foldbomb five)
(const_int i8_type (-1))
(const_int i8_type 0)) m);
let zero = const_int i32_type 0 in
let one = const_int i32_type 1 in
ignore (define_global "const_extractelement" (const_extractelement
Expand Down
18 changes: 0 additions & 18 deletions llvm/test/Bitcode/select.ll

This file was deleted.

4 changes: 2 additions & 2 deletions llvm/test/Bitcode/thinlto-function-summary-callgraph-cast.ll
Expand Up @@ -9,7 +9,7 @@
; "op7" is a call to "callee" function.
; CHECK-NEXT: <PERMODULE {{.*}} op7=3 op8=[[ALIASID:[0-9]+]]/>
; "another_caller" has only references but no calls.
; CHECK-NEXT: <PERMODULE {{.*}} op4=3 {{.*}} op9={{[0-9]+}}/>
; CHECK-NEXT: <PERMODULE {{.*}}/>
; CHECK-NEXT: <PERMODULE {{.*}} op0=[[ALIASEEID:[0-9]+]]
; CHECK-NEXT: <ALIAS {{.*}} op0=[[ALIASID]] {{.*}} op2=[[ALIASEEID]]/>
; CHECK-NEXT: <BLOCK_COUNT op0=3/>
Expand All @@ -27,7 +27,7 @@ define void @caller() {

define void @another_caller() {
; Test calls that aren't handled either as direct or indirect.
call void select (i1 icmp eq (ptr @global, ptr null), ptr @f, ptr @g)()
call void getelementptr (i8, ptr @f, i64 ptrtoint (ptr @g to i64))()
ret void
}

Expand Down

0 comments on commit bbfb13a

Please sign in to comment.