downloadmirror.intel.com is now fronted by an AWS WAF bot challenge that
returns an empty HTTP 202 to non-browser clients, so unattended wget
downloads of Intel SDE produce a 0-byte file that breaks `tar` (exit 2)
in the dependency-install step of every Linux/Windows CI job.
Host the SDE tarballs as a release asset on ispc.dependencies and fetch
them the same way as LLVM (via the new SDE_REPO variable, parallel to
LLVM_REPO). Drop the now-unused SDE_MIRROR_ID and USER_AGENT variables
and validate the downloaded file is an xz archive before extracting so a
bad download fails loudly instead of feeding garbage to tar. Also fix a
latent bug in install-svml-test-deps.sh that untarred a .tar.bz2 from a
.tar.xz download.
Requires a matching sde-external-9.58.0-2025-06-16 release with
-lin.tar.xz and -win.tar.xz assets on ispc.dependencies.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Modifications to headers included by builtins/builtins-c-cpu.cpp
(builtins-c-common.hpp, array.hpp, src/builtins-info.h) did not
trigger a rebuild because add_custom_command in builtin_to_cpp and
builtin_wasm_to_cpp only listed the .cpp file in DEPENDS.
Add BUILTINS_C_CPU_HEADER_DEPS, mirroring the existing
M4_IMPLICIT_DEPENDENCIES pattern, and pass it to DEPENDS in both
functions so a header edit correctly rebuilds the four bitcode
targets.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When a function has dead varying code (e.g. `uint8 y = x[0]` where y is
unused), ISPC generates a masked load in the `some_on` path. After
optimization, the unused masked load gets reduced by InstCombine to a
select with the passthrough value:
%res = select <8 x i1> %mask, <8 x i8> %x, <8 x i8> undef
This select flows into a phi node in the common return block:
%rv = phi <8 x i8> [ %res, %loop ], [ %x, %entry ], [ %x, %some_on ]
%ret = add <8 x i8> %rv, splat (i8 1)
ret <8 x i8> %ret
LLVM cannot simplify `select(mask, x, undef)` to `x` because undef
semantics require each use to independently pick an arbitrary value,
so folding would change the possible outcomes. With the phi having
non-identical incoming values, SimplifyCFG cannot merge the blocks,
leaving the mask-checking control flow (vmovmskps/vtestps/cmp/jmp)
in the final assembly as dead weight.
Changing the passthrough from `undef` to `poison` fixes this because
`select(mask, x, poison)` legally simplifies to `x` as poison is
strictly more permissive. This makes all phi incoming values identical
(%x), allowing SimplifyCFG to collapse the three blocks into one and
eliminate the redundant branches entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add step 6 to the "Implementing a feature or fixing a bug" workflow in
CLAUDE.md instructing to check git history of changed files after the
fix is implemented, to verify no previously fixed bugs were
re-introduced. Documents git log --oneline, git log -L and git show
as useful commands for this purpose.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The commit f80c6e0c changed I1VecToBoolVec to produce [N x <W x iMASK>]
for bool short-vector comparison results, intending to make varying bool<N>
consistent with scalar varying bool (which uses BoolVectorType = iMASK
internally). However it did not update lGetVectorLLVMType, which still
returned [N x <W x i8>] (storage type) for VectorType::LLVMType() on
varying bool<N>. This mismatch caused "Call parameter type does not match
function signature" when a comparison result was passed directly to a
function expecting bool<N>.
Fix: complete the original intent by removing the !base->IsUniformType()
exception in lGetVectorLLVMType so that LLVMType() for varying bool<N>
returns [N x <W x iMASK>] (consistent with I1VecToBoolVec), while
LLVMStorageType() continues to return [N x <W x i8>]. Update TypeCastExpr
to match: build the output array with LLVMType and use SwitchBoolToMaskType
for bool elements in both the vector-to-vector and scalar-to-vector paths.
This design is now fully symmetric: both scalar varying bool and varying
bool<N> use the target-specific mask type internally (e.g. i32 on AVX2,
i1 on AVX-512) and convert to i8 only at store/load/ABI boundaries.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ispc-opt runs optimization passes on LLVM IR and does not require the
bitcode libraries provided by the builtin target. Previously, it was
linked against builtin primarily to satisfy a target validation check in
the Target constructor that relies on the target registry.