This is an archive of the discontinued LLVM Phabricator instance.

[DAG] canCreateUndefOrPoison - add support for SRA/SRL shift opcode (WIP)
Changes PlannedPublic

Authored by RKSimon on Oct 22 2022, 8:16 AM.

Details

Summary

Right shifts won't create undef/poison if they are inexact with inrange shift amounts.

Matches handling in Operator::hasPoisonGeneratingFlags()

WIP: There are still a few regression cases to handle (either other missing opcodes or we are freezing ops that we can't push the freeze through multiple operands), but I'm cleaning out old branches and wanted to get this up for future reference.

Diff Detail

Unit TestsFailed

Event Timeline

RKSimon created this revision.Oct 22 2022, 8:16 AM
RKSimon requested review of this revision.Oct 22 2022, 8:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 22 2022, 8:16 AM
RKSimon planned changes to this revision.Oct 22 2022, 8:16 AM
foad added a comment.Jan 5 2023, 7:07 AM

Right shifts won't create undef/poison if they are exact with inrange shift amounts.

If they are inexact, surely?

RKSimon edited the summary of this revision. (Show Details)Jan 5 2023, 7:23 AM
RKSimon planned changes to this revision.Feb 8 2023, 7:59 AM
RKSimon planned changes to this revision.Feb 8 2023, 12:28 PM
RKSimon added inline comments.Feb 11 2023, 11:32 AM
llvm/test/CodeGen/RISCV/rv64zbb.ll
255

@craig.topper I'm familiar with the riscv shift code, but moving the freeze out of the way has changed:

t2: i64,ch = CopyFromReg t0, Register:i64 %0
    t127: i64 = and t2, Constant:i64<4294967295>
  t30: i64 = srl t127, Constant:i64<1>

to

  t2: i64,ch = CopyFromReg t0, Register:i64 %0
t4: i64 = AssertZext t2, ValueType:ch:i31
  t32: i64 = srl t4, Constant:i64<1>
t33: i64 = or t4, t32
craig.topper added inline comments.Feb 11 2023, 11:25 PM
llvm/test/CodeGen/RISCV/rv64zbb.ll
255

srliw is a 32-bit shift right in a 64-bit register. It's equivalent to (srl (and X, 0xffffffff), C).

Looks like SimplifyDemandedBits is not figuring out that bit 31 is zero due to the AssertZExt.

So we end up with (srl (and X, 0x7fffffff), C) instead.

We don't have an and with immediate for that constant so we use a shift left followed by shift right for the combination.

I tried adding a computeKnownBits call during isel to try to recover the mask, but it looks like it hit the depth limit before it got to the AssertZExt.

I think all the ANDs before every SRL after type legalization allowed us to propagate more information before some of them they got removed. Some weird visitation order I guess.