[RFC] Remove most constant expressions

Thank you for your work on this!

Scalable vectors can’t occur as global variable initializers, so at least that part of the equation doesn’t change, right? IRBuilder already has a CreateVectorSplat method which is a good first step.

From a quick glance, it seems that the worst pain point may be that Constant::getIntegerValue and even ConstantInt::get and friends can be applied to vector-of-int types to produce splats. If we want to get rid of those constant expressions (and I lean towards “yes”), it looks like an important first step would be to dig into the fall-out of removing those code paths.

Huzzah! This makes me soooo happy!

Well I guess this is convenient based on how the code used to work, now it should loop over all the users and insert corresponding instructions I think?



I’m happy to see constantexpr go away and appreciate this effort, could we introduce a new kind of splat constant to support this case? Being forced to use instructions could be a problem for scalable vectors. Consider that these instructions could be hoisted out of a loop by LICM, where it would be preferable to observe the constant in the expression that used it (think of add immediates, for example).

What if we declared that ConstantInt and ConstantFP can be of vector type, in which case they represent a splat?


I really like that idea. At least conceptually, this makes a lot of sense to me and should help ensure that scalars and vector splats receive consistent handling, because they really should. In practice, I’d expect this will break assumptions people have been making, e.g. because constants get recreated with scalar types.

How would we spell such a constant in IR? At least the scalable vector case would need some dedicated syntax.

It would be good to not preclude their use for fixed vectors too, it’s unpleasant to count the commas if you have a 512 x something.

As a strawman: Is there something wrong with vectype splat value e.g. <8 x i32> splat 42?

1 Like

As a small status update, the following constant expressions have been removed to date:

  • select
  • fneg
  • fadd
  • fsub
  • fmul
  • fdiv
  • frem
  • udiv
  • urem
  • sdiv
  • srem
  • and
  • or
  • zext
  • sext
  • fptrunc
  • fpext
  • fptoui
  • fptosi
  • uitofp
  • sitofp
  • extractvalue
  • insertvalue

The following are still scheduled for removal:

  • mul
  • shl
  • xor
  • icmp
  • fcmp
  • lshr
  • ashr
  • extractelement
  • insertelement
  • shufflevector

mul expressions are currently blocked on flang ([flang] Don't generate mul constant expressions · Issue #71507 · llvm/llvm-project · GitHub).

insertelement/shufflevector are blocked on scalable vector splats, hopefully soon resolved by [RFC] Scalable Vector Constants Splats.

Not aware of any specific issues for the rest, they likely just need work to remove remaining uses.

1 Like

If we go through with [RFC] LLVM IR should allow bitcast between address spaces with the same size we could also eliminate constantexpr addrspacecast

As I understand it, bitcast and addrspacecast would have quite different semantics in that case – is it true that we would never need the addrspacecast semantics in global initializers?

Currently only no-op addrspacecast constant expressions are supported, otherwise we just error. The no-op case should be covered by bitcast

Is that no-op only invariant enforced anywhere? I ask because in my address space 7 lowering PR, I could write tests involving addrspacecast ptr addrspace(8) [const] to ptr addrspace(7) … which is a shift left (and has to be some sort of transformation, since the pointers are of different sizes), not a noop.

@krzysz00 It’s enforced here: https://github.com/llvm/llvm-project/blob/80d3a4c39f5065ef620d7b3e73935cf491f0c394/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp#L3026-L3034

Restrictions on constant expression initializers only get enforced in the backend, otherwise we allow all initializers.

Targets can overwrite that method though, and I know that NVPTX has this code: https://github.com/llvm/llvm-project/blob/80d3a4c39f5065ef620d7b3e73935cf491f0c394/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp#L1990-L1995 I have no idea whether that’s a no-op address space cast or not.

This is super awesome @nikic, thank you for driving this forward!