Issue 203414
Summary [AArch64] bool-packing loops at -O2 compile to a movemask wrapped in a dead stack frame and redundant masking
Labels
Assignees
Reporter joseph-isaacs
    # What happens

The following code (https://godbolt.org/z/7nvcor895) results in a unused `sp` operation.

```cpp
uint8_t above_threshold(const float* v, float t) {
    uint8_t m = 0;
    for (int i = 0; i < 8; i++)
        m |= (uint32_t)(v[i] > t) << i;
    return m;
}
```

`clang -O2 --target=aarch64-linux-gnu` compiles this to:
      
```llvm
define i8 @above_threshold(ptr %v, float %t) { 
 %0 = load <8 x float>, ptr %v, align 4 
  %1 = insertelement <8 x float> poison, float %t, i64 0 
  %2 = shufflevector <8 x float> %1, <8 x float> poison, <8 x i32> zeroinitializer 
  %3 = fcmp ogt <8 x float> %0, %2 
  %4 = bitcast <8 x i1> %3 to i8
  ret i8 %4 
}
```

```asm
above_threshold:
    sub  sp, sp, #16              ; <- nothing below ever touches memory
    ldp  q1, q2, [x0]
    adrp x8, .LCPI0_0
    dup  v0.4s, v0.s[0]
    fcmgt v2.4s, v2.4s, v0.4s
    fcmgt v0.4s, v1.4s, v0.4s
    ldr  q1, [x8, :lo12:.LCPI0_0]
    uzp1 v0.8h, v0.8h, v2.8h
    and  v0.16b, v0.16b, v1.16b
    addv h0, v0.8h
    fmov w8, s0
    and  w0, w8, #0xff            
    add  sp, sp, #16 ; <-
    ret
```

# How it can be fixed

There are likely two fix complementary fixes:
 1. Have `vectorToScalarBitmask` lower this `bitcast <8 x i1> %3 to i8` via a `8 x i16` register.
 2. Find the place where the lowering via the stack is replaced and fix up the `FrameIndex`.

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to