This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] ctlz(x) -> 0 if x is known negative number
AbandonedPublic

Authored by xbolva00 on May 4 2021, 8:32 AM.

Details

Reviewers
RKSimon
spatel
Summary
----------------------------------------
define i32 @src(i32 %x, i1 %zerodef) {
%0:
  %assume = icmp slt i32 %x, 0
  assume i1 %assume
  %c = ctlz i32 %x, %zerodef
  ret i32 %c
}
=>
define i32 @tgt(i32 %x, i1 %zerodef) {
%0:
  %assume = icmp slt i32 %x, 0
  assume i1 %assume
  ret i32 0
}
Transformation seems to be correct!

Proof: https://alive2.llvm.org/ce/z/rU6o1d
Solves second case in https://bugs.llvm.org/show_bug.cgi?id=50173

Diff Detail

Event Timeline

xbolva00 created this revision.May 4 2021, 8:32 AM
xbolva00 requested review of this revision.May 4 2021, 8:32 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 4 2021, 8:32 AM
xbolva00 updated this revision to Diff 342757.May 4 2021, 8:44 AM
xbolva00 retitled this revision from [InstSimplify] ctlz(zext(x)) -> 0 if X is known negative number to [InstSimplify] ctlz(x) -> 0 if x is known negative number.
xbolva00 edited the summary of this revision. (Show Details)

Generalization.

RKSimon added inline comments.May 4 2021, 9:01 AM
llvm/test/Transforms/InstSimplify/call.ll
1490

please pre-commit the new tests and rebase

spatel added inline comments.May 4 2021, 9:39 AM
llvm/lib/Analysis/InstructionSimplify.cpp
5412–5413 ↗(On Diff #342757)

Enhance isKnownNegative to know that ashr of negative constant is still negative? Then we could remove the match here.

xbolva00 marked an inline comment as done.May 4 2021, 10:31 AM
xbolva00 added inline comments.
llvm/lib/Analysis/InstructionSimplify.cpp
5412–5413 ↗(On Diff #342757)

Yeah

5412–5413 ↗(On Diff #342757)

As followup I think.

RKSimon accepted this revision.May 4 2021, 11:02 AM

LGTM

This revision is now accepted and ready to land.May 4 2021, 11:02 AM
craig.topper added a subscriber: craig.topper.EditedMay 4 2021, 11:23 AM

What's the advantage of doing this in InstSimplfy when InstCombine can already do it via computeKnownBits? Is ctlz common enough for this to matter for the places that use InstSimplify directly?

xbolva00 added a comment.EditedMay 4 2021, 11:35 AM

No strong opinion, but everybody should agree.

I really dont want to go with “instsimplify -> instcombine -> instsimplify” patches.

isKnownNegative is just a wrapper around computeKnownBits. So if we are to do this in InstSimplify we might as well take the whole code that was already flagged in InstCombineCalls that can already do this and more.

KnownBits Known = IC.computeKnownBits(Op0, 0, &II);                                                                                                                                                  
                                                                                                                                                                                                     
// Create a mask for bits above (ctlz) or below (cttz) the first known one.                                                                                                                          
unsigned PossibleZeros = IsTZ ? Known.countMaxTrailingZeros()                                                                                                                                        
                              : Known.countMaxLeadingZeros();                                                                                                                                        
unsigned DefiniteZeros = IsTZ ? Known.countMinTrailingZeros()                                                                                                                                        
                              : Known.countMinLeadingZeros();                                                                                                                                        
                                                                                                                                                                                                     
// If all bits above (ctlz) or below (cttz) the first known one are known                                                                                                                            
// zero, this value is constant.                                                                                                                                                                     
// FIXME: This should be in InstSimplify because we're replacing an                                                                                                                                  
// instruction with a constant.                                                                                                                                                                      
if (PossibleZeros == DefiniteZeros) {                                                                                                                                                                
  auto *C = ConstantInt::get(Op0->getType(), DefiniteZeros);                                                                                                                                         
  return IC.replaceInstUsesWith(II, C);                                                                                                                                                              
}
xbolva00 added a comment.EditedMay 4 2021, 12:27 PM

// FIXME: This should be in InstSimplify because we're replacing an ...

Not sure, if we want to then compute known bits in instcombine just for:

if (!Known.One.isNullValue() ||
    isKnownNonZero(Op0, IC.getDataLayout(), 0, &IC.getAssumptionCache(), &II,
                   &IC.getDominatorTree())) {
  if (!match(II.getArgOperand(1), m_One()))
    return IC.replaceOperand(II, 1, IC.Builder.getTrue());
}

For now I think I will move this code to instcombine.

Enhance isKnownNegative to know that ashr of negative constant is still negative? Then we could remove the match here.

In this case, please feel free to enhance computeKnownBits/computeSignBits.

xbolva00 updated this revision to Diff 342836.May 4 2021, 1:03 PM
xbolva00 retitled this revision from [InstSimplify] ctlz(x) -> 0 if x is known negative number to [InstCombine] ctlz(x) -> 0 if x is known negative number.

Moved to InstCombine.

Moved to InstCombine.

Your test already passes before your change. If the Known bits is negative, PossibleZeros and DefiniteZeros will both be 0 which triggers the PossibleZeros == DefiniteZeros case.

xbolva00 abandoned this revision.May 4 2021, 2:02 PM

Moved to InstCombine.

Your test already passes before your change. If the Known bits is negative, PossibleZeros and DefiniteZeros will both be 0 which triggers the PossibleZeros == DefiniteZeros case.

ah, yes.