```
define internal void @foo() {
ret void
}
define i64 @main() {
ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -2147483626)
}
```
When `foo` is a local symbol, `foo` and `main` are in the same section,
and `offset` is near INT32_MIN, referencing `foo+offset` in `main` with
RIP-relative addressing needs `leaq .text+offset1(%rip), %rax` where
`offset1 < offset`, and `offset1` might underflow.
(https://discourse.llvm.org/t/arithmetic-referencing-dso-local-function-causes-compilation-error-on-linux-x64/80033):
Don't use RIP-relative addressing if the negative offset is near
INT32_MIN. Arbitrarily reuse the magic number in isOffsetSuitableForCodeModel to
guard against the edge case when `address(current_instruction)-foo < 4GiB-16MiB`.
If the difference is larger than 4GiB-16MiB, `ret i64 add (i64 ptrtoint
(ptr @foo to i64), i64 -2**32+256MiB)` would still cause the assembly
issue, such cases are unrealistic.
Pull Request: https://github.com/llvm/llvm-project/pull/98438
Alongside something like:
vpternlogq zmm0, zmm2, zmm1, 64
We will now have a comment on the right like:
# zmm0 = zmm0 & zmm2 & ~zmm1
This makes it easy to tell at a glance what sort of truth table the
instruction will provide.
This reapplies commit 1911a50fae8a441b445eb835b98950710d28fc88 with a
minor fix in lld/ELF/LTO.cpp which sets Options.BBAddrMap when
`--lto-basic-block-sections=labels` is passed.
This feature is supported via the newer option
`-fbasic-block-address-map`. Using the old option still works by
delegating to the newer option, while a warning is printed to show
deprecation.
In ExpandFPLibCall, an assumption is made that all floating point
libcalls that take integer arguments use unsigned integers. In the case
of ldexp and frexp, this assumption is incorrect, leading to
miscompilation and subsequent target-dependent incorrect operation.
Indicate that ldexp and frexp utilize signed arguments in
ExpandFPLibCall.
Fixes#108904
Signed-off-by: Timothy Pearson <tpearson@solidsilicon.com>
Allow setting the computed properties IsSSA, NoPHIs, NoVRegs for MIR
functions in MIR input. The default value is still the computed value.
If the property is set to false, the computed result is ignored. Conflicting
values (e.g. setting IsSSA where the input MIR is clearly not SSA) lead to
an error.
Closes#37787
Minor improvement on cc39c3b17fb2598e20ca0854f9fe6d69169d85c7.
Use an aligned stack slot to store the shifted value.
Use the native register width as shifting unit, so the load of the
shift result is aligned.
If the shift amount is a multiple of the native register width, there is
no need to do a follow-up shift after the load. I added new tests for
these cases.
Co-authored-by: Gergely Futo <gergely.futo@hightec-rt.com>
x86 vector ISAs are non-orthogonal in a number of ways. For example,
AVX2 has vpsravd but it does not have vpsravw. However, we can simulate
it via vpsrlvd and some SWAR-style masking.
Another example is 8-bit shifts: we can use vpsllvd to simulate the
missing "vpsllvb" if shift amounts can be shared for a single lane.
Existing code generation would use a variety of techniques including
vpmulhuw which is higher latency and often has more rigid port
requirements than simple bitwise operations.
This fixes#108936, but the calling convention doesn't match with GCC. I
doubt we have such a lib function for now, so leave the calling
convention as is.
For cross-lane shuffles, extract the mask operand (uppper) subvector directly, and make use of the free implicit extraction of the lowest subvector of the result.
Reverted due to large .debug_line size regressions for some
configurations; work currently in place to improve the output of this
behaviour in PR #108251.
This patch also modifies two tests that were created or modified after
the original commit landed and are affected by the revert:
llvm/test/CodeGen/X86/pseudo_cmov_lower2.ll
llvm/test/DebugInfo/X86/empty-line-info.ll
This reverts commit 5fef40c2c477e92187bd4e5c18091eca6b8465cc.
Use SWAR techniques for arithmetic shifts: we use the same technique as
logical right shift but with an additional step of sign extending the
result.
Also, use the logical shift left technique even on AVX512 as vpmovzxbw
and vpmovwb are actually quite expensive.
This PR is related to #99591. In this PR, instead of modifying how the
legalisation occurs depending on surrounding instructions, we refine
after legalisation.
This PR has two parts:
* `SDPatternMatch/MatchContext`: Modify a little bit the code to match
Operands (used by `m_Node(...)`) and Unary/Binary/Ternary Patterns to
make it compatible with `VPMatchContext`, instead of only `m_Opc`
supported. Some tests were added to ensure no regressions.
* `DAGCombiner`: Add a `foldSubCtlzNot` which detect and rewrite the
patterns using matching context.
Remaining Tasks:
- [ ] GlobalISel
- [ ] Currently the pattern matching will occur even before
legalisation. Should I restrict it to specific stages instead ?
- [ ] Style: Add a visitVP_SUB ?? Move `foldSubCtlzNot` in another
location for style consistency purpose ?
@topperc
---------
Co-authored-by: v01dxyz <v01dxyz@v01d.xyz>
This is a follow-up to #92289 that adds lowering of the new
`@llvm.experimental.vector.compress` intrinsic on x86 with AVX512
instructions. This intrinsic maps directly to `vpcompress`.
SSE & AVX do not include instructions for shifting i8 vectors. Instead,
they must be synthesized via other instructions.
If pairs of i8 vectors share a shift amount, we can use SWAR techniques
to substantially reduce the amount of code generated.
Say we were going to execute this shift right:
x >> {0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, ...}
LLVM would previously generate:
vpxor %xmm1, %xmm1, %xmm1
vpunpckhbw %ymm0, %ymm1, %ymm2
vpunpckhbw %ymm1, %ymm0, %ymm3
vpsllw $4, %ymm3, %ymm3
vpblendd $204, %ymm3, %ymm2, %ymm2
vpsrlw $8, %ymm2, %ymm2
vpunpcklbw %ymm0, %ymm1, %ymm3
vpunpcklbw %ymm1, %ymm0, %ymm0
vpsllw $4, %ymm0, %ymm0
vpblendd $204, %ymm0, %ymm3, %ymm0
vpsrlw $8, %ymm0, %ymm0
vpackuswb %ymm2, %ymm0, %ymm0
Instead, we can reinterpret a pair of i8 elements as an i16 and shift
use the same shift amount. The only thing we need to do is mask out any
bits which crossed the boundary from the top i8 to the bottom i8.
This SWAR-style technique achieves:
vpsrlw $4, %ymm0, %ymm1
vpblendd $170, %ymm1, %ymm0, %ymm0
vpand .LCPI0_0(%rip), %ymm0, %ymm0
This is implemented for both left and right logical shift operations.
Arithmetic shifts are less well behaved here because the shift cannot
also perform the sign extension for the lower 8 bits.
Add tests for "sub(select(icmp(a,b),a,b),select(icmp(a,b),b,a)) -> abd(a,b)" patterns that still fail to match to abd nodes
This will hopefully be helped by #108218