Issue 137274
Summary AArch64 backend incorrectly lowers `mul` into `umull`
Labels new issue
Assignees
Reporter vector542
    The AArch64 backend incorrectly lowers `mul` into `umull` when a smaller than full-width pre/post index load precedes the instruction. Here is a minimum reproducible example that can be compiled with Clang:
```cpp
#include <cstdint>

uint64_t test(uint64_t *ptr) {
 uint64_t a = *ptr + 8;
    uint64_t b = *(uint32_t *)a;
    return a * b;
}
```

It outputs this assembly:
```asm
ldr     x8, [x0]
ldr w9, [x8, #8]!
umull   x0, w8, w9
ret
```
This is incorrect as `umull` performs a 32-bit input to 64-bit output multiplication. The instruction should be `mul` for 64-bit inputs. [For reference, GCC and MSVC correctly compile it.](https://godbolt.org/z/jKnovWjr7)

The backend appears to think that the upper 32 bits of `x8` are zero, which triggers this rewrite:
```
def : Pat<(i64 (mul top32Zero:$Rn, top32Zero:$Rm)),
 (UMADDLrrr (EXTRACT_SUBREG $Rn, sub_32), (EXTRACT_SUBREG $Rm, sub_32), XZR)>;
```

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to