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