[llvm-bugs] [Bug 40172] New: [WebAssembly] Incorrect FastISel of icmp + zext due to missing masking
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Dec 28 04:12:57 PST 2018
https://bugs.llvm.org/show_bug.cgi?id=40172
Bug ID: 40172
Summary: [WebAssembly] Incorrect FastISel of icmp + zext due to
missing masking
Product: libraries
Version: trunk
Hardware: PC
OS: All
Status: NEW
Severity: enhancement
Priority: P
Component: Backend: WebAssembly
Assignee: unassignedbugs at nondot.org
Reporter: nikita.ppv at gmail.com
CC: llvm-bugs at lists.llvm.org
Originally reported at: https://github.com/rust-lang/rust/issues/57152
For LLVM IR:
define void @test(i8 %byte) {
%t = alloca { i8, i8 }, align 1
%x4 = and i8 %byte, 1
%x5 = icmp eq i8 %x4, 1
%x6 = and i8 %byte, 2
%x7 = icmp eq i8 %x6, 2
%x8 = bitcast { i8, i8 }* %t to i8*
%x9 = zext i1 %x5 to i8
store i8 %x9, i8* %x8, align 1
%x10 = getelementptr inbounds { i8, i8 }, { i8, i8 }* %t, i32 0, i32 1
%x11 = zext i1 %x7 to i8
store i8 %x11, i8* %x10, align 1
ret void
}
An llc -O0 -mtriple=wasm32 -debug trace shows:
bb.0 (%ir-block.0):
liveins: $arguments
%0:i32 = ARGUMENT_i32 0, implicit $arguments
%10:i32 = CONST_I32 2, implicit-def $arguments
%5:i32 = COPY %0:i32
%14:i32 = CONST_I32 2, implicit-def dead $arguments
%7:i32 = AND_I32 %0:i32, killed %14:i32, implicit-def dead $arguments
%8:i32 = CONST_I32 255, implicit-def $arguments
%9:i32 = AND_I32 %7:i32, %8:i32, implicit-def $arguments
%11:i32 = CONST_I32 255, implicit-def $arguments
%12:i32 = AND_I32 %10:i32, %11:i32, implicit-def $arguments
%13:i32 = EQ_I32 %9:i32, %12:i32, implicit-def $arguments
%6:i32 = COPY %5:i32
STORE8_I32 0, 0, %stack.0.t, %6:i32, implicit-def $arguments :: (store 1 into
%ir.x8)
%3:i32 = COPY %13:i32
STORE8_I32 0, 1, %stack.0.t, %3:i32, implicit-def $arguments :: (store 1 into
%ir.x10)
RETURN_VOID implicit-def $arguments
The first STORE8_I32 stores %6, which is a COPY of %5 which is a copy of %0, so
it stores the argument directly, rather than the argument masked with 1.
Looking at debug output, we can see that the first icmp generates this
SelectionDAG fragment:
t2: i32,ch = CopyFromReg t0, Register:i32 %0
t3: i8 = truncate t2
t5: i8 = and t3, Constant:i8<1>
t7: i1 = setcc t5, Constant:i8<1>, seteq:ch
t8: i32 = any_extend t7
t10: ch = CopyToReg t0, Register:i32 %5, t8
Which then (correctly) combines down to:
t2: i32,ch = CopyFromReg t0, Register:i32 %0
t10: ch = CopyToReg t0, Register:i32 %5, t2
That is, the masking has been removed *on the assumption that only the lowest
bit is significant*. Note that the any_extend above has been generated as part
of a copy to a virtual export register.
However, FastISel for WebAssembly has a reverse assumption in
https://github.com/llvm-mirror/llvm/blob/78dfeb7de614170c9deebe990c9f0f5aa838d5b6/lib/Target/WebAssembly/WebAssemblyFastISel.cpp#L448
that the result of an icmp will always be 0 or 1.
I'm not totally sure what the right way to fix this is. The conservative fix
would be to remove the specialized code for (zext (icmp)) from wasm FastISel,
but probably there's a better way to do this.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181228/6c5a95b5/attachment-0001.html>
More information about the llvm-bugs
mailing list