Fixes https://bugs.llvm.org/show_bug.cgi?id=40172. See
test/CodeGen/WebAssembly/PR40172.ll for an explanation.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
lib/Target/WebAssembly/WebAssemblyFastISel.cpp | ||
---|---|---|
451 ↗ | (On Diff #180745) | Maybe I'm lacking the context. How does this code check if this is lowered by FastISel of DAG ISel fallback? |
452 ↗ | (On Diff #180745) | This case clause is entered only when From == MVT::i1. Do we need to check it again here? |
test/CodeGen/WebAssembly/bug-40172.ll | ||
3 ↗ | (On Diff #180745) | Nit: It seems people add bug-related test cases in the name of PRXXXXX.ll. (I'm not sure what PR stands for. Do you know?) Maybe better to follow that convention. So in this case it will be PR40172.ll. Fix the comment/CL description too. |
7 ↗ | (On Diff #180745) | invalidating? |
lib/Target/WebAssembly/WebAssemblyFastISel.cpp | ||
---|---|---|
451 ↗ | (On Diff #180745) | I do not know of a way to tell whether or how something has already been lowered, so I just removed the optimization. I suppose to be safe I should remove the Argument optimization as well, since I certainly can't prove that it's correct. This change makes us generate worse code in lots of places, but since it is FastISel perhaps it doesn't matter so much? |
lib/Target/WebAssembly/WebAssemblyFastISel.cpp | ||
---|---|---|
451 ↗ | (On Diff #180745) | FastISel selects instructions in reverse order, so at this point the icmp hasn't been selected yet and there's no way to tell -- it would only be possible to replicate the checks FastISel does and ensure they'll all be true. That seems somewhat fragile though. |
lib/Target/WebAssembly/WebAssemblyFastISel.cpp | ||
---|---|---|
451 ↗ | (On Diff #180745) | @sunfish, it seems to me that we do know for sure that i1 Arguments will always produce a 0 or a 1 because there is no way DAG ISel could combine away an Argument node. This is in contrast to the compare node, which could be combined away by DAG ISel. Does that seem right to you? |
test/CodeGen/WebAssembly/PR40172.ll | ||
---|---|---|
7 ↗ | (On Diff #180936) | I didn't quite understand what happened, so I ran the current code over this test case. Right after instruction selection, the mir code is bb.0 (%ir-block.0): liveins: $arguments %0:i32 = ARGUMENT_i32 0, implicit $arguments %12:i32 = CONST_I32 2, implicit-def $arguments %6:i32 = COPY %0:i32 %16:i32 = CONST_I32 2, implicit-def dead $arguments %9:i32 = AND_I32 %0:i32, killed %16:i32, implicit-def dead $arguments %10:i32 = CONST_I32 255, implicit-def $arguments %11:i32 = AND_I32 %9:i32, %10:i32, implicit-def $arguments %13:i32 = CONST_I32 255, implicit-def $arguments %14:i32 = AND_I32 %12:i32, %13:i32, implicit-def $arguments %15:i32 = EQ_I32 %11:i32, %14:i32, implicit-def $arguments // Following two lines are added by this patch %7:i32 = CONST_I32 1, implicit-def $arguments %8:i32 = AND_I32 %6:i32, %7:i32, implicit-def $arguments STORE8_I32 0, 0, %stack.0.t, %8:i32, implicit-def $arguments :: (store 1 into %ir.x8) // Following two lines are added by this patch %3:i32 = CONST_I32 1, implicit-def $arguments %4:i32 = AND_I32 %15:i32, %3:i32, implicit-def $arguments STORE8_I32 0, 1, %stack.0.t, %4:i32, implicit-def $arguments :: (store 1 into %ir.x10) RETURN_VOID implicit-def $arguments The values (registers) that are newly masked are %6 and %15, where %6 is an argument %0:i32 = ARGUMENT_i32 0, implicit $arguments %6:i32 = COPY %0:i32 and %15 is a result of EQ_i32. %15:i32 = EQ_I32 %11:i32, %14:i32, implicit-def $arguments The argument does not seem to have a reason not to be i1, and also isn't the result of EQ supposed to be i1 as well..? I think I'm missing something. |
test/CodeGen/WebAssembly/PR40172.ll | ||
---|---|---|
7 ↗ | (On Diff #180936) | There are no i1s after instruction selection because type legalization has promoted them to i32s. However, they should still have i1 semantics, so %6 should have been truncated to a 0 or 1 rather than just copied directly. |