Skip to content

Splat of not could be canonicalised #63868

@lukel97

Description

@lukel97

Alive link: https://alive2.llvm.org/ce/z/4KIIpC

If we have a scalar value that we want to negate and then splat, we can either:

  1. negate the scalar, then splat
  2. splat it, then negate the vector
define <2 x i32> @src(i32 %x, <2 x i32> %y) {
  %not.x = xor i32 %x, -1
  %not.x.head = insertelement <2 x i32> poison, i32 %not.x, i64 0
  %not.x.splat = shufflevector <2 x i32> %not.x.head, <2 x i32> poison, <2 x i32> zeroinitializer
  %res = and <2 x i32> %not.x.splat, %y
  ret <2 x i32> %res
}

define <2 x i32> @tgt(i32 %x, <2 x i32> %y) {
  %x.head = insertelement <2 x i32> poison, i32 %x, i64 0
  %x.splat = shufflevector <2 x i32> %x.head, <2 x i32> poison, <2 x i32> zeroinitializer
  %not.x.splat = xor <2 x i32> %x.splat, shufflevector (<2 x i32> insertelement (<2 x i32> poison, i32 -1, i32 0), <2 x i32> poison, <2 x i32> zeroinitializer)
  %res = and <2 x i32> %not.x.splat, %y
  ret <2 x i32> %res
}

InstCombine doesn't seem to canonicalise it, but I think it could be beneficial to transform to the former.
This would aid in instruction selection for some instructions like vandn.vx on RISC-V

(Excuse the gratuitous splatting: this originally came from an example on scalable vectors, but I had to convert it to fixed for it to work on Alive)

Metadata

Metadata

Assignees

No one assigned

    Labels

    llvm:instcombineCovers the InstCombine, InstSimplify and AggressiveInstCombine passes

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions