aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ModuleManager.cpp
diff options
context:
space:
mode:
authorLuke Lau <luke@igalia.com>2025-05-13 02:11:55 +0300
committerGitHub <noreply@github.com>2025-05-13 00:11:55 +0100
commitcf3242f3b0f6eec47786426777f6e0b18363caa1 (patch)
tree17b957ad22ed6961c49e2022bff06f00f9f342db /clang/lib/Serialization/ModuleManager.cpp
parent9981afc5f9d1bb84e35d562f2a1d0f6bf56fcb58 (diff)
downloadllvm-cf3242f3b0f6eec47786426777f6e0b18363caa1.zip
llvm-cf3242f3b0f6eec47786426777f6e0b18363caa1.tar.gz
llvm-cf3242f3b0f6eec47786426777f6e0b18363caa1.tar.bz2
[InstCombine] Pull shuffles out of binops with splatted ops (#137948)
Given a binary op on splatted vector and a splatted constant, InstCombine will normally pull the shuffle out in `InstCombinerImpl::foldVectorBinop`: ```llvm define <4 x i32> @f(i32 %x) { %x.insert = insertelement <4 x i32> poison, i32 %x, i64 0 %x.splat = shufflevector <4 x i32> %x.insert, <4 x i32> poison, <4 x i32> zeroinitializer %res = add <4 x i32> %x.splat, splat (i32 42) ret <4 x i32> %res } ``` ```llvm define <4 x i32> @f(i32 %x) { %x.insert = insertelement <4 x i32> poison, i32 %x, i64 0 %1 = add <4 x i32> %x.insert, <i32 42, i32 poison, i32 poison, i32 poison> %res = shufflevector <4 x i32> %1, <4 x i32> poison, <4 x i32> zeroinitializer ret <4 x i32> %res } ``` However, this currently only operates on fixed length vectors. Splats of scalable vectors don't currently have their shuffle pulled out, e.g: ```llvm define <vscale x 4 x i32> @f(i32 %x) { %x.insert = insertelement <vscale x 4 x i32> poison, i32 %x, i64 0 %x.splat = shufflevector <vscale x 4 x i32> %x.insert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer %res = add <vscale x 4 x i32> %x.splat, splat (i32 42) ret <vscale x 4 x i32> %res } ``` Having this canonical form with the shuffle pulled out is important as VectorCombine relies on it in order to scalarize binary ops in `scalarizeBinopOrCmp`, which would prevent the need for #137786. This also brings it in line for scalable binary ops with two non-constant operands: https://godbolt.org/z/M9f7ebzca This adds a combine just after the fixed-length version, but restricted to splats at index 0 so that it also handles the scalable case: So the whilst the existing combine looks like: `Op(shuffle(V1, Mask), C) -> shuffle(Op(V1, NewC), Mask)` This patch adds: `Op(shuffle(V1, 0), (splat C)) -> shuffle(Op(V1, (splat C)), 0)` I think this could be generalized to other splat indexes that aren't zero, but I think it would be dead code since only fixed-length vectors can have non-zero shuffle indices, which would be covered by the existing combine.
Diffstat (limited to 'clang/lib/Serialization/ModuleManager.cpp')
0 files changed, 0 insertions, 0 deletions