I stumbled onto a case where our (sext_inreg (assertzexti32 (fptoui X)), i32)
isel pattern can cause an fcvt.wu and fcvt.lu to be emitted if
the assertzexti32 has an additional user. If we add a one use check
it would just cause a fcvt.lu followed by a sext.w when only need
a fcvt.wu to satisfy both users.
To mitigate this I've added custom isel and new ISD opcodes for
fcvt.wu. This allows us to keep know it started life as a conversion
to i32 without needing to match multiple nodes. ComputeNumSignBits
has been taught that this new nodes produces 33 sign bits. To
prevent regressions when we need to zero extend the result of an
(i32 (fptoui X)), I've added a DAG combine to convert it to an
(i64 (fptoui X)) before type legalization. In most cases this would
happen in InstCombine, but a zero_extend can be created for function
returns or arguments.
To keep everything consistent I've added new nodes for fptosi as well.
Reviewed By: luismarques
Differential Revision: https://reviews.llvm.org/D106346
When BasicTTIImpl::getCastInstrCost can't determine the cost of a
vector cast operation when the types need legalization, it falls
back to calculating scalarization costs. Instead of crashing on
`cast<FixedVectorType>(DstVTy)` when the type is a scalable vector,
return an Invalid cost.
Reviewed By: david-arm
Differential Revision: https://reviews.llvm.org/D106655
Many of the tests have used NEXT when DAG is more approprite. In
some cases single DAG lines have been used. Note that these are
manual tests because they're to complex for update_llc_test_checks.py
and so it's worth not relying too much on the ordered output.
I've also made the CHECK lines more uniform when it comes to the
ordering of things like LO/HI.
If value tracking can confirm that the cttz/ctlz source is known non-zero then we don't need to create a branch (which DAG will struggle to recover from).
Differential Revision: https://reviews.llvm.org/D106685
Most other registers are allocatable and therefore cannot be used.
This issue was flagged by the machine verifier, because reading other
registers is considered reading from an undefined register.
Differential Revision: https://reviews.llvm.org/D96969
This patch fixes some issues with the RORB pseudo instruction.
- A minor issue in which the instructions were said to use the SREG,
which is not true.
- An issue with the BLD instruction, which did not have an output operand.
- A major issue in which invalid instructions were generated. The fix
also reduce RORB from 4 to 3 instructions, so it's also a small
optimization.
These issues were flagged by the machine verifier.
Differential Revision: https://reviews.llvm.org/D96957
This patch makes sure shift instructions such as this one:
%result = shl i32 %n, %amount
are expanded just before the IR to SelectionDAG conversion to a loop so
that calls to non-existing library functions such as __ashlsi3 are
avoided. The generated code is currently pretty bad but there's a lot of
room for improvement: the shift itself can be done in just four
instructions.
Differential Revision: https://reviews.llvm.org/D96677
There were some serious issues with atomic operations. This patch should
fix the biggest issues.
For details on the issue take a look at this Compiler Explorer sample:
https://godbolt.org/z/n3ndhn
Code:
void atomicadd(_Atomic char *val) {
*val += 5;
}
Output:
atomicadd:
movw r26, r24
ldi r24, 5 ; 'operand' register
in r0, 63
cli
ld r24, X ; load value
add r24, r26 ; value += X
st X, r24 ; store value back
out 63, r0
ret ; return the wrong value (in r24)
There are various problems with this.
- The value to add (5) is stored in r24. However, the value to add to
is loaded in the same register: r24.
- The `add` instruction adds half of the pointer to the loaded value,
instead of (attempting to) add the operand with value 5.
- The output value of the cmpxchg instruction (which is not used in
this code sample) is the new value with 5 added, not the old value.
The LangRef specifies that it has to be the old value, before the
operation.
This patch fixes the first two and leaves the third problem to be fixed
at a later date. I believe atomics were mostly broken before this patch,
with this patch they should become usable as long as you ignore the
output of the atomic operation. In particular it fixes the following
things:
- It sets the earlyclobber flag for the input ('$operand' operand) so
that the register allocator puts it in a different register than the
output value.
- It fixes a number of issues with the pseudo op expansion pass, for
example now it adds the $operand field instead of the pointer. This
fixes most machine instruction verifier issues (other flagged issues
are unrelated to atomics).
Differential Revision: https://reviews.llvm.org/D97127
In most cases, using R31R30 is fine because the call (which always
precedes ADJCALLSTACKDOWN) will clobber R31R30 anyway. However, in some
rare cases the register allocator might insert an instruction between
the call and the ADJCALLSTACKDOWN instruction and expect the register
pair to be live afterwards. I think this happens as a result of
rematerialization. Therefore, to fix this, the instruction needs to have
Defs set to R31R30.
Setting the Defs field does have the effect of making the instruction
look dead, which it certainly is not. This is fixed by setting
hasSideEffects to true.
Differential Revision: https://reviews.llvm.org/D97745
Previously, AVRTargetLowering::LowerCall attempted to keep stack stores
in order with chains. Perhaps this worked in the past, but it does not
work now: it appears that the SelectionDAG legalization phase removes
these chains. Therefore, I've removed these chains entirely to match
X86 (which, similar to AVR, also prefers to use push instructions over
stack-relative stores to set up a call frame). With this change, all the
stack stores are in a somewhat reasonable order.
Differential Revision: https://reviews.llvm.org/D97853
I've setup the basic framework for the isGuaranteedNotToBeUndefOrPoison call and updated DAGCombiner::visitFREEZE to use it, further Opcodes can be handled when we have test coverage.
I'm not aware of any vector test freeze coverage so the DemandedElts (and the Depth) args are not being used yet - but they are in place.
SelectionDAG::isGuaranteedNotToBePoison wrappers have also been added.
Differential Revision: https://reviews.llvm.org/D106668
In D106041, a freeze was added before the branch condition to solve the miscompilation problem of SimpleLoopUnswitch.
However, I found that the added freeze disturbed other optimizations in the following situations.
```
arg.fr = freeze(arg)
use(arg.fr)
...
use(arg)
```
It is a problem that occurred when arg and arg.fr were recognized as different values.
Therefore, changing to use arg.fr instead of arg throughout the function eliminates the above problem.
Thus, I add a function that changes all uses of arg to freeze(arg) to visitFreeze of InstCombine.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D106233
Currently when linking LLVM against Libxml2, a simple check is performed to check whether it can be linked successfully. This check currently adds the include directories and the libraries for libxml2, but not definitions found by the config.
This causes issues on Windows when trying to link against a static libxml2. Libxml2 requires LIBXML_STATIC to be defined in the preprocessor to be able to link statically. This definition is put into LIBXML2_DEFINITIONS in the cmake config, but not properly forwarded to check_symbol_exists leading to it failing as it could not find xmlReadMemory in a DLL.
This patch simply appends the content of LIBXML2_DEFINITIONS to the symbol check definitions, fixing the issue.
Differential Revision: https://reviews.llvm.org/D106740
This is just a workaround. Pass the `-mllvm,-O0` link flags only if its
not ThinLTO. Doing that with ThinLTO currently results in an error:
```
Remaining virtual register operands
UNREACHABLE executed at .../llvm/lib/CodeGen/MachineRegisterInfo.cpp:209!
```
This patch introduces a pass that uses the Attributor to deduce AMDGPU specific attributes.
Reviewed By: jdoerfert, arsenm
Differential Revision: https://reviews.llvm.org/D104997
* ELF supports `nodeduplicate`.
* ELF calls the concept "section group". `GRP_COMDAT` emulates the PE COMDAT deduplication feature.
* "COMDAT group" is an ELF term. Avoid it for PE/COFF.
* WebAssembly supports comdat but only supports the `any` selection kind. https://bugs.llvm.org/show_bug.cgi?id=50531
* A comdat must be included or omitted as a unit. Both the compiler and the linker must obey this rule.
* A global object can be a member of at most one comdat.
* COFF requires a non-local linkage for non-`nodeduplicate` selection kinds.
* llvm.global_ctors/.llvm.global_dtors: if the third field is used on ELF, it must reference a global variable or function in a comdat
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D106300
checkForAllInstructions was not handling declarations correctly.
It should have been returning false when it gets called on a declaration
The patch also fixes a test case for AAFunctionReachability for it to be able
to pass after the changes to the checkForAllinstructions.
Differential Revision: https://reviews.llvm.org/D106625
This is referenced in several of the cmake files that are part of an llvm install and it is also useful by downstream components such as onnx-mlir.
Differential Revision: https://reviews.llvm.org/D106686
Eli pointed out the issue when reviewing D104140. The max trip count logic makes an assumption that the value of IV changes. When the step is zero, the nowrap fact becomes trivial, and thus there's nothing preventing the loop from being nearly infinite. (The "nearly" part is because mustprogress may disallow an infinite loop while still allowing 999999999 iterations before RHS happens to allow an exit.)
This is very difficult to see in practice. You need a means to produce a loop varying RHS in a mustprogress loop which doesn't allow the loop to be infinite. In most cases, LICM or SCEV are smart enough to remove the loop varying expressions.
Differential Revision: https://reviews.llvm.org/D106327
This was previously combining indices even though they operate on
different types. For non-opaque pointers, the condition is
automatically satisfied based on the pointer types being equal.
Replace the clang builtins and LLVM intrinsics for {f32x4,f64x2}.{pmin,pmax}
with standard codegen patterns. Since wasm_simd128.h uses an integer vector as
the standard single vector type, the IR for the pmin and pmax intrinsic
functions contains bitcasts that would not be there otherwise. Add extra codegen
patterns that can still select the pmin and pmax instructions in the presence of
these bitcasts.
Differential Revision: https://reviews.llvm.org/D106612
Otherwise e.g. the FoldTwoEntryPHINode() has to do a lot of legwork
to re-deduce what is the dominant block (i.e. for which block
is this branch the terminator).
The check for sinking instructions past the load + cmp sequence
currently checks for side-effects, which includes writing to memory
and unwinding. However, I don't believe we care about sinking the
instructions past an unwind (as they don't have any side-effects
themselves).
Differential Revision: https://reviews.llvm.org/D106591
This matches what MS rc.exe allows in practice. I'm not aware of
any legal syntax case that are broken by allowing dashes as part
of what the tokenizer considers an Identifier - but I'm not
very well versed in the RC syntax either, can @amccarth think of
any case that would be broken by this?
This fixes downstream bug
https://github.com/msys2/MINGW-packages/issues/9180.
Additionally, rc.exe allows such resource name strings to be surrounded
by quotes, ending up with e.g.
Resource name (string): "QUOTEDNAME"
(i.e., the quotes end up as part of the string), which llvm-rc doesn't
support yet either. (I'm not aware of such cases in the wild though,
but resource string names with dashes do exist.)
This also allows including files with unquoted paths, with filenames
containing dashes (which fixes
https://github.com/msys2/MINGW-packages/issues/9130, which has been
worked around differently so far).
Differential Revision: https://reviews.llvm.org/D106598
Avoid buffering just to copy the buffered data, in 'development
mode', when logging. Instead, just populate the underlying protobuf.
Differential Revision: https://reviews.llvm.org/D106592