This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Canonicalize ssub.with.overflow to ssub.sat
ClosedPublic

Authored by dmgreen on Nov 2 2019, 1:06 PM.

Details

Summary

Working on top of D69252, this adds canonicalisation patterns for ssub.with.overflow to ssub.sats.

These are the alive patterns being selected, all of which pass:

Name: SSub_x_lt0
  %ao = ssub_overflow i8 %x, %y
  %a = extractvalue %ao, 0
  %o = extractvalue %ao, 1
  %c = icmp slt i8 %x, 0
  %s = select i1 %c, i8 -128, i8 127
  %x5 = select i1 %o, i8 %s, i8 %a
=>
  %x5 = ssub_sat %x, %y

Name: SSub_x_lt1
  %ao = ssub_overflow i8 %x, %y
  %a = extractvalue %ao, 0
  %o = extractvalue %ao, 1
  %c = icmp slt i8 %x, -1
  %s = select i1 %c, i8 -128, i8 127
  %x5 = select i1 %o, i8 %s, i8 %a
=>
  %x5 = ssub_sat %x, %y

Name: SSub_x_lg2
; Not valid.
  %ao = ssub_overflow i8 %x, %y
  %a = extractvalue %ao, 0
  %o = extractvalue %ao, 1
  %c = icmp sgt i8 %x, -2
  %s = select i1 %c, i8 127, i8 -128
  %x5 = select i1 %o, i8 %s, i8 %a
=>
  %x5 = ssub_sat %x, %y

Name: SSub_x_lg1
  %ao = ssub_overflow i8 %x, %y
  %a = extractvalue %ao, 0
  %o = extractvalue %ao, 1
  %c = icmp sgt i8 %x, -1
  %s = select i1 %c, i8 127, i8 -128
  %x5 = select i1 %o, i8 %s, i8 %a
=>
  %x5 = ssub_sat %x, %y

Name: SSub_y_lt0
  %ao = ssub_overflow i8 %x, %y
  %a = extractvalue %ao, 0
  %o = extractvalue %ao, 1
  %c = icmp slt i8 %y, 0
  %s = select i1 %c, i8 127, i8 -128
  %x5 = select i1 %o, i8 %s, i8 %a
=>
  %x5 = ssub_sat %x, %y

Name: SSub_y_lt1
  %ao = ssub_overflow i8 %x, %y
  %a = extractvalue %ao, 0
  %o = extractvalue %ao, 1
  %c = icmp slt i8 %y, 1
  %s = select i1 %c, i8 127, i8 -128
  %x5 = select i1 %o, i8 %s, i8 %a
=>
  %x5 = ssub_sat %x, %y

Name: SSub_y_lg0
  %ao = ssub_overflow i8 %x, %y
  %a = extractvalue %ao, 0
  %o = extractvalue %ao, 1
  %c = icmp sgt i8 %y, 0
  %s = select i1 %c, i8 -128, i8 127
  %x5 = select i1 %o, i8 %s, i8 %a
=>
  %x5 = ssub_sat %x, %y

Name: SSub_y_lg1
  %ao = ssub_overflow i8 %x, %y
  %a = extractvalue %ao, 0
  %o = extractvalue %ao, 1
  %c = icmp sgt i8 %y, -1
  %s = select i1 %c, i8 -128, i8 127
  %x5 = select i1 %o, i8 %s, i8 %a
=>
  %x5 = ssub_sat %x, %y

Diff Detail

Event Timeline

dmgreen created this revision.Nov 2 2019, 1:06 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 2 2019, 1:06 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
lebedev.ri accepted this revision.Nov 10 2019, 10:00 AM

Such a pattern matching maze, wow.
Looks correct to me, but wouldn't hurt if someone else could also take a look (@nikic? @spatel ?)

This revision is now accepted and ready to land.Nov 10 2019, 10:00 AM

Such a pattern matching maze, wow.

It can at least be reduced similarly to the sadd_sat patch by bailing out early if Op is not X or Y. And maybe that makes it easier to combine the logic for ssub_sat and sadd_sat, but I'm not sure if that makes the code more confusing than it's worth.

Looks correct to me, but wouldn't hurt if someone else could also take a look (@nikic? @spatel ?)

Seems like the expected extension of the earlier patch, so LGTM.

dmgreen updated this revision to Diff 228628.Nov 10 2019, 3:22 PM

Update/rebase. Let me know if there's a better way to structure this that you can think of.

Update/rebase. Let me know if there's a better way to structure this that you can think of.

Ah, I didn't catch that asymmetry between add (commutative) and sub (not commutative). I don't have any good suggestions to make it shorter. Even if there is, it's better to commit this as-is to make sure the logic is correct in this form vs. any non-obvious reduced form.

This revision was automatically updated to reflect the committed changes.