openssl: export only the engine entry points
Upstream links every dynamic engine with a version script,
engines/<name>.ld, that exports bind_engine and v_check and makes
everything else local. FreeBSD's engines had no version script, so
they exported every global symbol, including _init and _fini.
loader_attic.so compiles its own copy of crypto/pem/pvkfmt.c and so
also exported 21 of its functions; 14 of them (b2i_*, i2b_*) have the
same names as public libcrypto functions.
Add one Version.map for all engines, the same as upstream's, and use it
from engines/Makefile.inc.
The engines are loaded only with dlopen(), and libcrypto looks up only
bind_engine and v_check, so hiding the other symbols does not affect
any consumer.
Tested via tinderbox: capi.so, devcrypto.so and loader_attic.so link
with --no-undefined-version and export only bind_engine and v_check.
[8 lines not shown]
openssl: fix engine defines to match upstream
Two engine Makefiles define different macros from upstream's
engines/build.info:
- padlock: engines/e_padlock.c builds the engine only when PADLOCK_ASM
is defined. Upstream defines it on x86 and x86_64, but our Makefile
never did, so padlock.so has been a stub whose bind_engine() returns
0 and the e_padlock-x86*.S code it links was never called. Define
PADLOCK_ASM on amd64 and i386, where that asm is built.
- loader_attic: upstream defines OPENSSL_NO_PROVIDER_CODE; the Makefile
had OPENSSL_NO_PROVIDER_CORE. No source tests either name, so the
build does not change; this only follows upstream.
Found by comparing per-file compile flags against an upstream 3.5.9
build. Checked by preprocessing e_padlock.c for amd64 and i386:
COMPILE_PADLOCKENG is now defined.
[5 lines not shown]
[LTO] Remove PreCodeGenPassesHook
This is unused in-tree after 74e4694b8cbd and it seems like there are no
users in public open source. This also makes porting to the NewPM
slightly more complicated if we want to preserve the functionality (for
which there are also no tests).
Reviewers: MaskRay, teresajohnson
Pull Request: https://github.com/llvm/llvm-project/pull/240236
MachineVerifier: Remove dead virtual register kill tracking (#240017)
Kill flags on virtual registers are now rejected, so the per-block
tracking of killed virtual registers can never report anything
new. Physical register kills are handled separately.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
[VPlan] Remove header masks whose tail lanes aren't used
Replace a use of header-mask && x with x if the user, transitively
through freeze, logical-and, not and mask.beforefirst(freeze ...), only
reaches masks that are and'ed with the header mask again. The header
mask is a prefix and lane i of mask.beforefirst only depends on lanes
0..i, so the lanes outside of the header mask are never used.
This avoids the i1 vp.merge that EVL tail folding needs for the inner
header mask, e.g. in the early exit mask.beforefirst(freeze(header-mask
&& c)) and in switch default edges.
[VPlan] Allow tail folding early exits with side effects
Continues the work in #179595.
This allows us to tail fold e.g. the following loop:
```c
extern char a[1024], b[1024], c[1024], y[1024];
void two_guards(void) {
for (int i = 0; i < 1000; i++) {
if (a[i] == 0)
break;
if (b[i] > 3) {
if (c[i] < 9)
y[i] = 1;
}
}
}
```
[30 lines not shown]
[VPlan] Support tail folding uncountable early exits
Enables the first step towards #179595. After #237254, the MaskedHandleExitInVectorLoop early exit style uses the CFG to handle masking for early exit loops. This allows it to compose with tail folding which is also handled via the CFG in #176143.
This allows us to tail fold the following loop:
```c
extern char x[256];
int f(char * restrict y) {
for (int i = 0; i < 256; i++) {
if (x[i] == 0)
return i;
}
return -1;
}
```
Into this on RISC-V:
[18 lines not shown]
[VPlan] Lower MaskedCond earlier in the predicator. NFC
A MaskedCond is used to logically-and some condition with the current block in mask.
It's currently lowered in convertToConcreteRecipes but we can just do it earlier in VPlanPredicator, which removes the need for the separate fold in simplifyRecipe. It also enables more logical-and simplifications earlier on.
[VPlan] Use vputils::findCanonicalIVIncrement in more places. NFC
In a future patch we want to enable more scenarios with early exits and tail folding. In these scenarios the terminator will no longer be a BranchOnCount/BranchOnCond but a BranchOnTwoConds, so a bunch of canonical IV matchers break. Use vputils::findCanonicalIVIncrement instead since it searches the users of the canonical IV instead of looking at the terminator.
[VPlan] Allow early exit loops with side effects by masking in the vector loop.
When all blocks with side effects are dominated by every early exit, we can vectorize the loop if we mask off any lanes past the exit. We can do this with control flow:
```mermaid
flowchart TD
header --> exiting
exiting -->| exit mask | sideeffects --> latch --> latch.split
exiting -->| !exit mask | latch.split
```
For every early exiting block we add a branch to the latch on `!mask.beforefirst(exitcond)`. This is implemented in UncountableExitStyle::ReadOnly which is now renamed to MaskedHandleExitInVectorLoop.
This is a complementary exit style to MaskedHandleExitInScalarLoop. If any of the side effects aren't dominated by the early exit it still falls back to the scalar loop style, which is why none of the existing early exit side effect tests changed. Masking in loop is profitable for RISC-V and I'm assuming it's also profitable for AArch64 too, but if not then we can add a TTI hook for a preferred exit style.
[VPlan] Preserve SSA in early exit loops
MaskedCond is used to logically-and the condition to early exit with the current block in-mask. However because we use it in the latch block where the condition isn't defined on all paths, we have to workaround it not being in SSA in the verifier.
This fixes this by using reconstructSSA added in #212209 to preserve SSA in both the exit conditions and live outs in the exit blocks. It also means we get the right exit condition without MaskedCond and allows us to remove the MaskedCond exceptions in the verifier. MaskedCond is still kept since a followup PR will still use it.
One subtle point is that we need to freeze any branch conditions. Any lanes after and including the early exiting lane might contain poison and we can have branches on those poison lanes that didn't we didn't previously branch on in the scalar loop.
There's no miscompile on main today because we coincidentally don't keep SSA so exit conditions are read directly without being polluted by poison stemming from a branch past the early exit. But in this PR the exit conditions are polluted and we can end up with poison in the condition operand of a select, which causes an undefined result for AnyOf even if it freezes its operand. The poison in the branch will also cause problems in future if we decide to preserve uniform control flow and emit branches instead of blends. The exit_cond_merged_after_poison_branch test illustrates this.
[VPlan] Simplify BLEND X/M, false, ..., false -> M && X
If an i1 blend has false for all but one incoming value, then we can simplify this to the one non-false value. Blends by construction never have any overlapping mask values, so we don't need to worry about the order as the masks can't "shortcut" each other.
[VPlan] Move extract-lane(0, canWideIV) combine before unrolling
Some extract-lane combines can't be performed before unrolling, e.g. the one that combines it to Instruction::ExtractElement can end up extracting from a different part. But the extract-lane(0, canWideIV) can because at index 0 you're always extracting from the first part. Do this before unrolling, which improves codegen of unrolled code.
[VPlan] Support interleaving early exit loops with side effects
We couldn't do this on main previously because the exit mask `active-lane-mask(0, FirstActiveLane(Cond))` doesn't get unrolled properly across parts. Now that we use mask.beforefirst we can unroll it properly in a chain. The unrolled form is:
unroll(mask.beforefirst, P) = mask.beforefirst(cond[P] | broadcast(anyof(not(unroll(mask.beforefirst, P-1)))))
On AArch64 this can be combined to brkpb in another patch.
[VPlan] Use llvm.mask.beforefirst for computing early exit mask
This makes the cost more accurate and improves codegen for RISC-V. The codegen for an early exit loop with side effects then goes from:
.LBB0_3: # %vector.body
# =>This Inner Loop Header: Depth=1
vl1r.v v16, (a3)
vsetvli zero, zero, e8, m1, ta, ma
vmseq.vi v16, v16, 0
vfirst.m a7, v16
srli t0, a7, 63
czero.nez a7, a7, t0
czero.eqz t0, a1, t0
or a7, t0, a7
vsetvli zero, zero, e64, m8, ta, ma
vmsltu.vx v0, v8, a7
vle8.v v17, (a5), v0.t
vcpop.m t1, v16
vsetvli zero, zero, e8, m1, ta, ma
[22 lines not shown]