Skip to content

[AVX2] vpsllvq builtin-semantics are not recognized by LLVM vectors #109888

@Validark

Description

@Validark

I wrote some Zig code trying to get the semantics of vpsllvq:

export fn foo(vec: @Vector(4, u64)) @Vector(4, u64) {
    return @select(
        u64,
        vec < @as(@Vector(4, u64), @splat(64)),
        @as(@Vector(4, u64), @splat(1)) << @truncate(vec),
        @as(@Vector(4, u64), @splat(0))
    );
}

Optimized LLVM:

define dso_local range(i64 0, -9223372036854775807) <4 x i64> @foo(<4 x i64> %0) local_unnamed_addr {
Entry:
  %1 = icmp ult <4 x i64> %0, <i64 64, i64 64, i64 64, i64 64>
  %2 = and <4 x i64> %0, <i64 63, i64 63, i64 63, i64 63>
  %3 = shl nuw <4 x i64> <i64 1, i64 1, i64 1, i64 1>, %2
  %4 = select <4 x i1> %1, <4 x i64> %3, <4 x i64> zeroinitializer
  ret <4 x i64> %4
}

Compiled for Zen 3:

.LCPI0_0:
        .quad   -9223372036854775808
.LCPI0_1:
        .quad   -9223372036854775745
.LCPI0_2:
        .quad   63
.LCPI0_3:
        .quad   1
foo:
        vpbroadcastq    ymm1, qword ptr [rip + .LCPI0_0]
        vpbroadcastq    ymm4, qword ptr [rip + .LCPI0_2]
        vpbroadcastq    ymm2, qword ptr [rip + .LCPI0_1]
        vpbroadcastq    ymm3, qword ptr [rip + .LCPI0_3]
        vpxor   ymm1, ymm0, ymm1
        vpand   ymm0, ymm0, ymm4
        vpcmpgtq        ymm1, ymm1, ymm2
        vpsllvq ymm0, ymm3, ymm0
        vpandn  ymm0, ymm1, ymm0
        ret

I was expecting just a vpsllvq instruction.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions