| Issue |
180774
|
| Summary |
[WebAssembly][FastISel] emits redundant explicit zext ('and') after unsigned loads
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
ParkHanbum
|
Description
When using FastISel (-fast-isel) for the WebAssembly target, the instruction selector emits redundant bitwise and instructions for zext operations, even when the source value was loaded using an unsigned load instruction (i32.load8_u or i32.load16_u).
Since i32.load8_u and i32.load16_u are guaranteed to zero-extend the value according to the WebAssembly specification, the subsequent explicit zero-extension (implemented as and with a mask) is unnecessary and should be optimized away, similar to how SelectionDAG handles it.
Reproduction Steps
Create a file named redundant_zext.ll with the following contentt:
sample:
```
define i32 @zext_i8_i32(ptr %p) {
e1:
%v = load atomic i8, ptr %p seq_cst, align 1
%e = zext i8 %v to i32
ret i32 %e
}
define i32 @zext_i16_i32(ptr %p) {
%v = load atomic i16, ptr %p seq_cst, align 2
%e = zext i16 %v to i32
ret i32 %e
}
```
isel resuts :
```
zext_i8_i32: # @zext_i8_i32
.functype zext_i8_i32 (i32) -> (i32)
# %bb.0: # %e1
local.get 0
i32.load8_u 0
zext_i16_i32: # @zext_i16_i32
.functype zext_i16_i32 (i32) -> (i32)
# %bb.0:
local.get 0
i32.load16_u 0
...
Current Behavior (Output)
The generated assembly includes unnecessary i32.const and i32.and instructions.
fast-isel results :
```
zext_i8_i32: # @zext_i8_i32
.functype zext_i8_i32 (i32) -> (i32)
# %bb.0: # %e1
local.get 0
i32.load8_u 0
i32.const 255
i32.and
end_function
zext_i16_i32: # @zext_i16_i32
.functype zext_i16_i32 (i32) -> (i32)
# %bb.0:
local.get 0
i32.load16_u 0
i32.const 65535
i32.and
end_function
```
Expected Behavior
The zext should be folded into the load instruction (or realized as a no-op), as the value is already zero-extended by the hardware instruction.
```
test_zext_i8:
local.get 0
i32.load8_u 0
# No 'and' instruction needed
end_function
test_zext_i16:
local.get 0
i32.load16_u 0
# No 'and' instruction needed
end_function
```
Additional Context
Target: WebAssembly (wasm32)
Component: WebAssemblyFastISel.cpp
Function: SelectZExt
Standard ISel (SelectionDAG) already optimizes this correctly. This seems to be a missed optimization opportunity in FastISel where it doesn't check if the operand is defined by a LOAD8_U or LOAD16_U instruction.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs