Skip to content

Commit

Permalink
[IR] Remove mul constant expression (#127046)
Browse files Browse the repository at this point in the history
Remove support for the mul constant expression, which has previously
already been marked as undesirable. This removes the APIs to create mul
expressions and updates tests to stop using mul expressions.

Part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
  • Loading branch information
nikic authored Feb 14, 2025
1 parent 0949330 commit d8b2e43
Show file tree
Hide file tree
Showing 31 changed files with 64 additions and 174 deletions.
3 changes: 0 additions & 3 deletions llvm/bindings/ocaml/llvm/llvm.ml
Original file line number Diff line number Diff line change
Expand Up @@ -655,9 +655,6 @@ external const_nuw_add : llvalue -> llvalue -> llvalue = "llvm_const_nuw_add"
external const_sub : llvalue -> llvalue -> llvalue = "llvm_const_sub"
external const_nsw_sub : llvalue -> llvalue -> llvalue = "llvm_const_nsw_sub"
external const_nuw_sub : llvalue -> llvalue -> llvalue = "llvm_const_nuw_sub"
external const_mul : llvalue -> llvalue -> llvalue = "llvm_const_mul"
external const_nsw_mul : llvalue -> llvalue -> llvalue = "llvm_const_nsw_mul"
external const_nuw_mul : llvalue -> llvalue -> llvalue = "llvm_const_nuw_mul"
external const_xor : llvalue -> llvalue -> llvalue = "llvm_const_xor"
external const_gep : lltype -> llvalue -> llvalue array -> llvalue
= "llvm_const_gep"
Expand Down
14 changes: 0 additions & 14 deletions llvm/bindings/ocaml/llvm/llvm.mli
Original file line number Diff line number Diff line change
Expand Up @@ -1131,20 +1131,6 @@ val const_nsw_sub : llvalue -> llvalue -> llvalue
See the method [llvm::ConstantExpr::getNSWSub]. *)
val const_nuw_sub : llvalue -> llvalue -> llvalue

(** [const_mul c1 c2] returns the constant product of two constants.
See the method [llvm::ConstantExpr::getMul]. *)
val const_mul : llvalue -> llvalue -> llvalue

(** [const_nsw_mul c1 c2] returns the constant product of two constants with
no signed wrapping. The result is undefined if the sum overflows.
See the method [llvm::ConstantExpr::getNSWMul]. *)
val const_nsw_mul : llvalue -> llvalue -> llvalue

(** [const_nuw_mul c1 c2] returns the constant product of two constants with
no unsigned wrapping. The result is undefined if the sum overflows.
See the method [llvm::ConstantExpr::getNSWMul]. *)
val const_nuw_mul : llvalue -> llvalue -> llvalue

(** [const_xor c1 c2] returns the constant bitwise [XOR] of two integer
constants.
See the method [llvm::ConstantExpr::getXor]. *)
Expand Down
18 changes: 0 additions & 18 deletions llvm/bindings/ocaml/llvm/llvm_ocaml.c
Original file line number Diff line number Diff line change
Expand Up @@ -1210,24 +1210,6 @@ value llvm_const_nuw_sub(value LHS, value RHS) {
return to_val(Value);
}

/* llvalue -> llvalue -> llvalue */
value llvm_const_mul(value LHS, value RHS) {
LLVMValueRef Value = LLVMConstMul(Value_val(LHS), Value_val(RHS));
return to_val(Value);
}

/* llvalue -> llvalue -> llvalue */
value llvm_const_nsw_mul(value LHS, value RHS) {
LLVMValueRef Value = LLVMConstNSWMul(Value_val(LHS), Value_val(RHS));
return to_val(Value);
}

/* llvalue -> llvalue -> llvalue */
value llvm_const_nuw_mul(value LHS, value RHS) {
LLVMValueRef Value = LLVMConstNUWMul(Value_val(LHS), Value_val(RHS));
return to_val(Value);
}

/* llvalue -> llvalue -> llvalue */
value llvm_const_xor(value LHS, value RHS) {
LLVMValueRef Value = LLVMConstXor(Value_val(LHS), Value_val(RHS));
Expand Down
4 changes: 0 additions & 4 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5113,10 +5113,6 @@ The following is the syntax for constant expressions:
Perform an addition on constants.
``sub (LHS, RHS)``
Perform a subtraction on constants.
``mul (LHS, RHS)``
Perform a multiplication on constants.
``shl (LHS, RHS)``
Perform a left shift on constants.
``xor (LHS, RHS)``
Perform a bitwise xor on constants.

Expand Down
13 changes: 13 additions & 0 deletions llvm/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ Changes to the LLVM IR
----------------------

* The `nocapture` attribute has been replaced by `captures(none)`.
* The constant expression variants of the following instructions have been
removed:

* `mul`

Changes to LLVM infrastructure
------------------------------
Expand Down Expand Up @@ -121,6 +125,15 @@ Changes to the Python bindings
Changes to the C API
--------------------

* 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:

* `LLVMConstMul`
* `LLVMConstNUWMul`
* `LLVMConstNSWMul`

Changes to the CodeGen infrastructure
-------------------------------------

Expand Down
3 changes: 0 additions & 3 deletions llvm/include/llvm-c/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -2459,9 +2459,6 @@ LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant)
LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
LLVMValueRef LLVMConstGEP2(LLVMTypeRef Ty, LLVMValueRef ConstantVal,
LLVMValueRef *ConstantIndices, unsigned NumIndices);
Expand Down
10 changes: 0 additions & 10 deletions llvm/include/llvm/IR/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -1143,8 +1143,6 @@ class ConstantExpr : public Constant {
bool HasNSW = false);
static Constant *getSub(Constant *C1, Constant *C2, bool HasNUW = false,
bool HasNSW = false);
static Constant *getMul(Constant *C1, Constant *C2, bool HasNUW = false,
bool HasNSW = false);
static Constant *getXor(Constant *C1, Constant *C2);
static Constant *getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced = false);
static Constant *getPtrToInt(Constant *C, Type *Ty,
Expand Down Expand Up @@ -1174,14 +1172,6 @@ class ConstantExpr : public Constant {
return getSub(C1, C2, true, false);
}

static Constant *getNSWMul(Constant *C1, Constant *C2) {
return getMul(C1, C2, false, true);
}

static Constant *getNUWMul(Constant *C1, Constant *C2) {
return getMul(C1, C2, true, false);
}

/// If C is a scalar/fixed width vector of known powers of 2, then this
/// function returns a new scalar/fixed width vector obtained from logBase2
/// of C. Undef vector elements are set to zero.
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4301,6 +4301,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
return error(ID.Loc, "ashr constexprs are no longer supported");
case lltok::kw_shl:
return error(ID.Loc, "shl constexprs are no longer supported");
case lltok::kw_mul:
return error(ID.Loc, "mul constexprs are no longer supported");
case lltok::kw_fneg:
return error(ID.Loc, "fneg constexprs are no longer supported");
case lltok::kw_select:
Expand Down Expand Up @@ -4329,7 +4331,6 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
// Binary Operators.
case lltok::kw_add:
case lltok::kw_sub:
case lltok::kw_mul:
case lltok::kw_xor: {
bool NUW = false;
bool NSW = false;
Expand Down
9 changes: 1 addition & 8 deletions llvm/lib/IR/Constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2422,10 +2422,10 @@ bool ConstantExpr::isSupportedBinOp(unsigned Opcode) {
case Instruction::LShr:
case Instruction::AShr:
case Instruction::Shl:
case Instruction::Mul:
return false;
case Instruction::Add:
case Instruction::Sub:
case Instruction::Mul:
case Instruction::Xor:
return true;
default:
Expand Down Expand Up @@ -2649,13 +2649,6 @@ Constant *ConstantExpr::getSub(Constant *C1, Constant *C2,
return get(Instruction::Sub, C1, C2, Flags);
}

Constant *ConstantExpr::getMul(Constant *C1, Constant *C2,
bool HasNUW, bool HasNSW) {
unsigned Flags = (HasNUW ? OverflowingBinaryOperator::NoUnsignedWrap : 0) |
(HasNSW ? OverflowingBinaryOperator::NoSignedWrap : 0);
return get(Instruction::Mul, C1, C2, Flags);
}

Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
return get(Instruction::Xor, C1, C2);
}
Expand Down
17 changes: 0 additions & 17 deletions llvm/lib/IR/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1803,23 +1803,6 @@ LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant,
unwrap<Constant>(RHSConstant)));
}

LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
return wrap(ConstantExpr::getMul(unwrap<Constant>(LHSConstant),
unwrap<Constant>(RHSConstant)));
}

LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant,
LLVMValueRef RHSConstant) {
return wrap(ConstantExpr::getNSWMul(unwrap<Constant>(LHSConstant),
unwrap<Constant>(RHSConstant)));
}

LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant,
LLVMValueRef RHSConstant) {
return wrap(ConstantExpr::getNUWMul(unwrap<Constant>(LHSConstant),
unwrap<Constant>(RHSConstant)));
}

LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) {
return wrap(ConstantExpr::getXor(unwrap<Constant>(LHSConstant),
unwrap<Constant>(RHSConstant)));
Expand Down
6 changes: 4 additions & 2 deletions llvm/test/Analysis/ValueTracking/known-non-equal.ll
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,13 @@ define i1 @mul5(i8 %B, i8 %C) {
define i1 @mul_constantexpr(i16 %a) {
; CHECK-LABEL: @mul_constantexpr(
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i16 [[A:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 mul nsw (i16 ptrtoint (ptr @g to i16), i16 -1), [[MUL]]
; CHECK-NEXT: [[MUL2:%.*]] = mul nsw i16 ptrtoint (ptr @g to i16), -1
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[MUL2]], [[MUL]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul nsw i16 %a, 3
%cmp = icmp eq i16 mul nsw (i16 ptrtoint (ptr @g to i16), i16 -1), %mul
%mul2 = mul nsw i16 ptrtoint (ptr @g to i16), -1
%cmp = icmp eq i16 %mul2, %mul
ret i1 %cmp
}

Expand Down
2 changes: 0 additions & 2 deletions llvm/test/Assembler/ConstantExprFold.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

@add = global ptr inttoptr (i64 add (i64 ptrtoint (ptr @A to i64), i64 0) to ptr) ; X + 0 == X
@sub = global ptr inttoptr (i64 sub (i64 ptrtoint (ptr @A to i64), i64 0) to ptr) ; X - 0 == X
@mul = global ptr inttoptr (i64 mul (i64 ptrtoint (ptr @A to i64), i64 0) to ptr) ; X * 0 == 0
@xor = global ptr inttoptr (i64 xor (i64 ptrtoint (ptr @A to i64), i64 0) to ptr) ; X ^ 0 == X

%Ty = type { i32, i32 }
Expand All @@ -33,7 +32,6 @@
; CHECK: @A = global i64 0
; CHECK: @add = global ptr @A
; CHECK: @sub = global ptr @A
; CHECK: @mul = global ptr null
; CHECK: @xor = global ptr @A
; CHECK: @B = external global %Ty
; CHECK: @cons = weak global i32 0, align 8
Expand Down
25 changes: 0 additions & 25 deletions llvm/test/Assembler/flags.ll
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,6 @@ define i64 @sub_both_ce() {
ret i64 sub nsw nuw (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define i64 @mul_both_ce() {
; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (ptr @addr to i64), i64 91)
ret i64 mul nuw nsw (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define ptr @gep_nw_ce() {
; CHECK: ret ptr getelementptr inbounds (i64, ptr @addr, i64 171)
ret ptr getelementptr inbounds (i64, ptr @addr, i64 171)
Expand All @@ -190,11 +185,6 @@ define i64 @sub_plain_ce() {
ret i64 sub (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define i64 @mul_plain_ce() {
; CHECK: ret i64 mul (i64 ptrtoint (ptr @addr to i64), i64 91)
ret i64 mul (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define ptr @gep_plain_ce() {
; CHECK: ret ptr getelementptr (i64, ptr @addr, i64 171)
ret ptr getelementptr (i64, ptr @addr, i64 171)
Expand All @@ -210,11 +200,6 @@ define i64 @sub_both_reversed_ce() {
ret i64 sub nsw nuw (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define i64 @mul_both_reversed_ce() {
; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (ptr @addr to i64), i64 91)
ret i64 mul nsw nuw (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define i64 @add_signed_ce() {
; CHECK: ret i64 add nsw (i64 ptrtoint (ptr @addr to i64), i64 91)
ret i64 add nsw (i64 ptrtoint (ptr @addr to i64), i64 91)
Expand All @@ -225,11 +210,6 @@ define i64 @sub_signed_ce() {
ret i64 sub nsw (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define i64 @mul_signed_ce() {
; CHECK: ret i64 mul nsw (i64 ptrtoint (ptr @addr to i64), i64 91)
ret i64 mul nsw (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define i64 @add_unsigned_ce() {
; CHECK: ret i64 add nuw (i64 ptrtoint (ptr @addr to i64), i64 91)
ret i64 add nuw (i64 ptrtoint (ptr @addr to i64), i64 91)
Expand All @@ -240,11 +220,6 @@ define i64 @sub_unsigned_ce() {
ret i64 sub nuw (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define i64 @mul_unsigned_ce() {
; CHECK: ret i64 mul nuw (i64 ptrtoint (ptr @addr to i64), i64 91)
ret i64 mul nuw (i64 ptrtoint (ptr @addr to i64), i64 91)
}

define i64 @test_zext(i32 %a) {
; CHECK: %res = zext nneg i32 %a to i64
%res = zext nneg i32 %a to i64
Expand Down
6 changes: 0 additions & 6 deletions llvm/test/Bindings/OCaml/core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,6 @@ let test_constants () =
* CHECK: @const_sub = global i64 sub
* CHECK: @const_nsw_sub = global i64 sub nsw
* CHECK: @const_nuw_sub = global i64 sub nuw
* CHECK: @const_mul = global i64 mul
* CHECK: @const_nsw_mul = global i64 mul nsw
* CHECK: @const_nuw_mul = global i64 mul nuw
* CHECK: @const_xor = global i64 xor
*)
let void_ptr = pointer_type context in
Expand All @@ -290,9 +287,6 @@ let test_constants () =
ignore (define_global "const_sub" (const_sub foldbomb five) m);
ignore (define_global "const_nsw_sub" (const_nsw_sub foldbomb five) m);
ignore (define_global "const_nuw_sub" (const_nuw_sub foldbomb five) m);
ignore (define_global "const_mul" (const_mul foldbomb five) m);
ignore (define_global "const_nsw_mul" (const_nsw_mul foldbomb five) m);
ignore (define_global "const_nuw_mul" (const_nuw_mul foldbomb five) m);
ignore (define_global "const_xor" (const_xor foldbomb five) m);

group "constant casts";
Expand Down
4 changes: 3 additions & 1 deletion llvm/test/CodeGen/ARM/2008-04-04-ScavengerAssert.ll
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ bb17.i: ; preds = %cond_next119.i
cond_true53.i: ; preds = %bb17.i
ret ptr null
cond_false99.i: ; preds = %bb17.i
%malloccall = tail call ptr @malloc(i32 trunc (i64 mul nuw (i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), i64 2) to i32))
%mul = mul nuw i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), 2
%trunc = trunc i64 %mul to i32
%malloccall = tail call ptr @malloc(i32 %trunc)
br i1 false, label %bb126.i, label %cond_next119.i
cond_next119.i: ; preds = %cond_false99.i, %bb42
%curr_ptr.0.reg2mem.0.i = phi ptr [ %malloccall, %cond_false99.i ], [ null, %bb42 ] ; <ptr> [#uses=2]
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/X86/ptrtoint-constexpr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

; CHECK: .globl x
; CHECK: x:
; CHECK: .quad 3
; CHECK: .quad 1+3

@x = global i64 mul (i64 3, i64 ptrtoint (ptr getelementptr (i2, ptr null, i64 1) to i64))
@x = global i64 add (i64 3, i64 ptrtoint (ptr getelementptr (i2, ptr null, i64 1) to i64))
16 changes: 0 additions & 16 deletions llvm/test/Other/constant-fold-gep-address-spaces.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,10 @@ target datalayout = "e-p:128:128:128-p1:32:32:32-p2:8:8:8-p3:16:16:16-p4:64:64:6
; The target-independent folder should be able to do some clever
; simplifications on sizeof, alignof, and offsetof expressions. The
; target-dependent folder should fold these down to constants.
; PLAIN-X: @a = constant i64 mul (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 2310)
@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint (ptr addrspace(4) getelementptr ({[7 x double], [7 x double]}, ptr addrspace(4) null, i64 11) to i64), i64 5))

; PLAIN-X: @b = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({ i1, double }, ptr null, i64 0, i32 1) to i64)
@b = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, [13 x double]}, ptr addrspace(4) null, i64 0, i32 1) to i64)

; PLAIN-X: @c = constant i64 mul nuw (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 2)
@c = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({double, double, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64)

; PLAIN-X: @d = constant i64 mul nuw (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 11)
@d = constant i64 ptrtoint (ptr addrspace(4) getelementptr ([13 x double], ptr addrspace(4) null, i64 0, i32 11) to i64)

; PLAIN-X: @e = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({ double, float, double, double }, ptr null, i64 0, i32 2) to i64)
@e = constant i64 ptrtoint (ptr addrspace(4) getelementptr ({double, float, double, double}, ptr addrspace(4) null, i64 0, i32 2) to i64)

Expand Down Expand Up @@ -123,10 +115,6 @@ define ptr addrspace(2) @hoo1() #0 {
ret ptr addrspace(2) %t
}

; PLAIN-X: define i64 @fa() #0 {
; PLAIN-X: %t = bitcast i64 mul (i64 ptrtoint (ptr addrspace(4) getelementptr (double, ptr addrspace(4) null, i32 1) to i64), i64 2310) to i64
; PLAIN-X: ret i64 %t
; PLAIN-X: }
; PLAIN-X: define i64 @fb() #0 {
; PLAIN-X: %t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({ i1, double }, ptr null, i64 0, i32 1) to i64) to i64
; PLAIN-X: ret i64 %t
Expand Down Expand Up @@ -159,10 +147,6 @@ define ptr addrspace(2) @hoo1() #0 {
; PLAIN-X: %t = bitcast i64 ptrtoint (ptr addrspace(2) getelementptr ({ i1, ptr addrspace(2) }, ptr null, i64 0, i32 1) to i64) to i64
; PLAIN-X: ret i64 %t
; PLAIN-X: }
define i64 @fa() #0 {
%t = bitcast i64 mul (i64 3, i64 mul (i64 ptrtoint (ptr getelementptr ({[7 x double], [7 x double]}, ptr null, i64 11) to i64), i64 5)) to i64
ret i64 %t
}
define i64 @fb() #0 {
%t = bitcast i64 ptrtoint (ptr addrspace(4) getelementptr ({i1, [13 x double]}, ptr addrspace(4) null, i64 0, i32 1) to i64) to i64
ret i64 %t
Expand Down
Loading

0 comments on commit d8b2e43

Please sign in to comment.