| Issue |
71844
|
| Summary |
WASM: Masking 64-bit Shifts After Zext
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
Geotale
|
Although capable of doing so after a 16-bit to 32-bit extension of an integer, WASM codegen appears not to be able to optimize the mask of a shift from a 32-bit to 64-bit extension.
```cpp
uint32_t test_32_16(uint32_t x, uint16_t y) {
return x << (y & 31);
}
uint64_t test_64_32(uint64_t x, uint32_t y) {
return x << (y & 63);
}
```
is equivalent to the two nearly identical IR functions:
```llvm
define i32 @test_32_16(i32 %x, i16 %y) {
%1 = and i16 %y, 31
%2 = zext i16 %1 to i32
%3 = shl i32 %x, %2
ret i32 %3
}
define i64 @test_64_32(i64 %x, i32 %y) {
%1 = and i32 %y, 63
%2 = zext i32 %1 to i64
%3 = shl i64 %x, %2
ret i64 %3
}
```
Compiling with any non-zero optimization level to wasm32-unknown-unknown gives:
```wasm
test_32_16: # @test_32_16
local.get 0
local.get 1
i32.shl
end_function
test_64_32: # @test_64_32
local.get 0
local.get 1
i32.const 63
i32.and
i64.extend_i32_u
i64.shl
end_function
```
with the first function eliminating the mask, and the second not doing so.
Clang 13 appears to be the first version in which `test_32_16` eliminates the mask.
https://godbolt.org/z/hYvaYs6xf
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs