InstCombine: Handle exp/exp2/exp10 in SimplifyDemandedFPClass
I'm working on optimizing out the tail sequences in the
implementations of the 4 different flavors of pow. These
include chains of selects on the various edge cases.
Related to #64870
ValueTracking: Add baseline tests for computeKnownFPClass exp
This is already handled, but misses opportunities. Test cases
where the input is known positive or negative.
ValueTracking: Avoid calling computeKnownFPClass on matched constant
The fmul case already tries to match a literal value, we don't
need to match it twice.
ValueTracking: Improve computeKnownFPClass fmul handling
Improve known non-nan sign bit tracking. Handle cases with
a known 0 or inf input of indeterminate sign.
The tails of some library functions have sign management
for special cases.
InstCombine: Handle canonicalize in SimplifyDemandedFPClass
Doesn't try to handle PositiveZero flushing mode, but I
don't believe it is incorrect with it.
ValueTracking: Avoid calling computeKnownFPClass on matched constant
The fmul case already tries to match a literal value, we don't
need to match it twice.
ValueTracking: Improve computeKnownFPClass fmul handling
Improve known non-nan sign bit tracking. Handle cases with
a known 0 or inf input of indeterminate sign.
The tails of some library functions have sign management
for special cases.
[clang][NFC] Use constructor instead of factory function in `CFGStmtMap` (#172530)
`CFGStmtMap::Build` accepts pointers and returns a pointer to
dynamically allocated memory. In the one location where the type is
actually constructed, the pointers are guaranteed to be non-null. By
accepting references to statically enforce this, we can remove the only
way for the construction to fail.
By making this change, we also allow our user to decide how they want to
own the memory (either directly or indirectly). The user does not
actually need dynamic allocation here, so we replace the
`std::unique_ptr` with `std::optional`.
This simplifies the code by requiring fewer checks, makes comments on
what happens redundant because the code can obviously do only one thing,
avoids potential bugs, and improves performance by allocating less.
[clang][NFC] Use constructor instead of factory function in `CFGStmtMap`
`CFGStmtMap::Build` accepts pointers and returns a pointer to dynamically allocated memory. In the one location where the type is actually constructed, the pointers are guaranteed to be non-null. By accepting references to statically enforce this, we can remove the only way for the construction to fail.
By making this change, we also allow our user to decide how they want to own the memory (either directly or indirectly). The user does not actually need dynamic allocation here, so we replace the `std::unique_ptr` with `std::optional`.
This simplifies the code by requiring fewer checks, makes comments on what happens redundant because the code can obviously do only one thing, avoids potential bugs, and improves performance by allocating less.
[NewPM][X86] Port X86ExpandPseudo to NPM (#173463)
Porting this over and adding it to the pipeline means we only need to
port AsmPrinter to fully lower very simple functions on X86.
[clang][NFC] In `CFGStmtMap`, do not use a `void *` data member, just use the object directly (#172528)
There is no reason to dynamically allocate `llvm::DenseMap` and try to
hide the type. A header we include anyway already includes `DenseMap.h`
so we save almost no compilation time. This change improves performance
by avoiding the dynamic allocation, and simplifies the code
considerably.
Now that we just have a regular data member, there is also no need for a
manual destructor, and the copy / move operations will do the right
thing.
In `getBlock`, we have some code that a comment claims is implementing
memoization, but in reality it does nothing. The relevant expression is
a conditional `(*SM)[X] = B`, but `B` is equal to `SM->find(X)->second`.
In `Accumulate`, we have a bunch of code to add things to the map for
the initial set-up. However, the original code would either find or
default construct an element, and then if the found element is equal to
[5 lines not shown]
[clang][NFC] In `CFGStmtMap`, do not use a `void *` data member, just use the object directly.
There is no reason to dynamically allocate `llvm::DenseMap` and try to hide the type. A header we include anyway already includes `DenseMap.h` so we save almost no compilation time. This change improves performance by avoiding the dynamic allocation, and simplifies the code considerably.
Now that we just have a regular data member, there is also no need for a manual destructor, and the copy / move operations will do the right thing.
In `getBlock`, we have some code that a comment claims is implementing memoization, but in reality it does nothing. The relevant expression is a conditional `(*SM)[X] = B`, but `B` is equal to `SM->find(X)->second`.
In `Accumulate`, we have a bunch of code to add things to the map for the initial set-up. However, the original code would either find or default construct an element, and then if the found element is equal to the default constructed element it would set it to `B`. Rather than doing this in two steps, we can simply use `try_emplace` to insert if it's not already present. This change is sound only if the new element we are inserting cannot be equal to the default constructed element, but the element type is a pointer and this entire section of code assumes `B` is not null.