Skip to content

[HLSL] Condition operand of select implicitly truncates non-boolean vectors #164018

@Icohedron

Description

@Icohedron

If the cond operand of select is given a vector that is not of boolean type or is a boolean vector produced from a boolean expression involving non-boolean vectors, then the vector implicitly gets truncated to its first element.

https://godbolt.org/z/7cP3xebfr

// compile args: -T lib_6_7 -Xclang -emit-llvm

export bool4 Foo(int4 a) {
    return select(a, (true).xxxx, (false).xxxx);
}

export bool4 Bar(int4 a) {
    return select(bool4(a), (true).xxxx, (false).xxxx);
}

Resulting IR (notice Foo and Bar are not equivalent):

define noundef <4 x i1> @Foo(int vector[4])(<4 x i32> noundef %a) local_unnamed_addr #0 {
entry:
  %0 = extractelement <4 x i32> %a, i64 0
  %cast.vtrunc.not = icmp eq i32 %0, 0
  %hlsl.select = select i1 %cast.vtrunc.not, <4 x i1> zeroinitializer, <4 x i1> splat (i1 true)
  ret <4 x i1> %hlsl.select
}

define noundef <4 x i1> @Bar(int vector[4])(<4 x i32> noundef %a) local_unnamed_addr #0 {
entry:
  %tobool = icmp ne <4 x i32> %a, zeroinitializer
  ret <4 x i1> %tobool
}

The same truncation occurs when using a logical comparison to produce a boolean vector from non-boolean vectors:
https://godbolt.org/z/PTYc18daG

// compile args: -T lib_6_7 -Xclang -emit-llvm

export bool4 Foo(int4 a, int4 b) {
    return select(a == b, (true).xxxx, (false).xxxx);
}

export bool4 Bar(int4 a, int4 b) {
    return select(bool4(a == b), (true).xxxx, (false).xxxx);
}
define noundef <4 x i1> @Foo(int vector[4], int vector[4])(<4 x i32> noundef %a, <4 x i32> noundef %b) local_unnamed_addr #0 {
entry:
  %cmp = icmp eq <4 x i32> %a, %b
  %.splat = shufflevector <4 x i1> %cmp, <4 x i1> poison, <4 x i32> zeroinitializer
  ret <4 x i1> %.splat
}

define noundef <4 x i1> @Bar(int vector[4], int vector[4])(<4 x i32> noundef %a, <4 x i32> noundef %b) local_unnamed_addr #0 {
entry:
  %cmp = icmp eq <4 x i32> %a, %b
  ret <4 x i1> %cmp
}

Metadata

Metadata

Assignees

Labels

HLSLHLSL Language Support

Type

No type

Projects

Status

Active

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions