This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly][FastISel] Do not assume naive CmpInst lowering
ClosedPublic

Authored by tlively on Jan 8 2019, 2:39 PM.

Diff Detail

Repository
rL LLVM

Event Timeline

tlively created this revision.Jan 8 2019, 2:39 PM
aheejin added inline comments.Jan 8 2019, 3:03 PM
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?
And real nit: Can we place the TODO in the next line?

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?

tlively marked an inline comment as done.Jan 8 2019, 3:08 PM
tlively added inline comments.
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?

tlively edited the summary of this revision. (Show Details)Jan 9 2019, 2:41 PM
tlively updated this revision to Diff 180936.Jan 9 2019, 2:48 PM
tlively marked 5 inline comments as done.
  • Address comments
tlively added inline comments.Jan 9 2019, 2:49 PM
lib/Target/WebAssembly/WebAssemblyFastISel.cpp
451 ↗(On Diff #180745)

I just removed the TODO. It is irrelevant anyway if we don't figure out how to tell if something has been lowered by FastISel.

452 ↗(On Diff #180745)

Nope, good catch.

nikic added inline comments.Jan 9 2019, 11:58 PM
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.

tlively marked an inline comment as done.Jan 11 2019, 10:42 AM
tlively added inline comments.
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?

aheejin added inline comments.Jan 12 2019, 4:46 PM
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.

tlively marked an inline comment as done.Jan 13 2019, 6:34 PM
tlively added inline comments.
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.

aheejin accepted this revision.Jan 14 2019, 1:25 PM
This revision is now accepted and ready to land.Jan 14 2019, 1:25 PM
This revision was automatically updated to reflect the committed changes.