Skip to content

Update implementation of built-in functions - #96

Merged
romanovvlad merged 11 commits into
intel:syclfrom
alexeyvoronov-intel:private/avoronov/update_builtins
Apr 21, 2019
Merged

romanovvlad merged 11 commits into
intel:syclfrom
alexeyvoronov-intel:private/avoronov/update_builtins

Conversation

@alexeyvoronov-intel

Copy link
Copy Markdown
Contributor

Add the host side integer and geometric built-in functions.
Refactoring of the host side built-in functions and built-in functions' tests.
Enable half variants of built-ins.

Added a wrapper of boolean vector.
Used the wrapper in the implementation of relational built-in functions.
Fixed isnormal for scalar double for the host side.
Fixed select for genfloatd and genfloath.

Signed-off-by: Alexey Voronov <[email protected]>
The GPU SPIRV translator cannot handle those function with
the vector first argument type and the scalar type second
/third argument together.

Signed-off-by: Alexey Voronov <[email protected]>
This function has the accuracy that implementation-defined and
cannot checked independed. Simply calling of this function is
checked by CTS.

Signed-off-by: Alexey Voronov <[email protected]>
Signed-off-by: Alexey Voronov <[email protected]>
Fix macro __HAFL_ENABLED.

Signed-off-by: Alexey Voronov <[email protected]>
Removed I/O.
Replace namespace cl::sycl to s for the tests.

Signed-off-by: Alexey Voronov <[email protected]>
Removed a code duplication.
Moved the common implementation functions to anonymous namespace.

Signed-off-by: Alexey Voronov <[email protected]>
@romanovvlad
romanovvlad merged commit 066adc4 into intel:sycl Apr 21, 2019
@alexeyvoronov-intel
alexeyvoronov-intel deleted the private/avoronov/update_builtins branch May 14, 2019 15:02
bb-sycl pushed a commit that referenced this pull request Feb 11, 2021
This patch implemented TTI.IntImmCost() properly.
Each BPF insn has 32bit immediate space, so for any immediate
which can be represented as 32bit signed int, the cost
is technically free. If an int cannot be presented as
a 32bit signed int, a ld_imm64 instruction is needed
and a TCC_Basic is returned.

This change is motivated when we observed that
several bpf selftests failed with latest llvm trunk, e.g.,
  #10/16 strobemeta.o:FAIL
  #10/17 strobemeta_nounroll1.o:FAIL
  #10/18 strobemeta_nounroll2.o:FAIL
  #10/19 strobemeta_subprogs.o:FAIL
  #96 snprintf_btf:FAIL

The reason of the failure is due to that
SpeculateAroundPHIsPass did aggressive transformation
which alters control flow for which currently verifer
cannot handle well. In llvm12, SpeculateAroundPHIsPass
is not called.

SpeculateAroundPHIsPass relied on TTI.getIntImmCost()
and TTI.getIntImmCostInst() for profitability
analysis. This patch implemented TTI.getIntImmCost()
properly for BPF backend which also prevented
transformation which caused the above test failures.

Differential Revision: https://reviews.llvm.org/D96448
iclsrc pushed a commit that referenced this pull request Dec 21, 2023
This PR adds support for thread names in lldb on Windows.

```
(lldb) thr list
Process 2960 stopped
  thread #53: tid = 0x03a0, 0x00007ff84582db34 ntdll.dll`NtWaitForMultipleObjects + 20
  thread #29: tid = 0x04ec, 0x00007ff845830a14 ntdll.dll`NtWaitForAlertByThreadId + 20, name = 'SPUW.6'
  thread #89: tid = 0x057c, 0x00007ff845830a14 ntdll.dll`NtWaitForAlertByThreadId + 20, name = 'PPU[0x1000019] physics[main]'
  thread #3: tid = 0x0648, 0x00007ff843c2cafe combase.dll`InternalDoATClassCreate + 39518
  thread #93: tid = 0x0688, 0x00007ff845830a14 ntdll.dll`NtWaitForAlertByThreadId + 20, name = 'PPU[0x100501d] uMovie::StreamingThread'
  thread #1: tid = 0x087c, 0x00007ff842e7a104 win32u.dll`NtUserMsgWaitForMultipleObjectsEx + 20
  thread #96: tid = 0x0890, 0x00007ff845830a14 ntdll.dll`NtWaitForAlertByThreadId + 20, name = 'PPU[0x1002020] HLE Video Decoder'
<...>
```
iclsrc pushed a commit that referenced this pull request Aug 6, 2025
… >= 4G (#151460)"

This reverts commit 600976f.

The test was crashing trying to access any element of the GPR struct.

(gdb) disas
Dump of assembler code for function _ZN7testing8internal11CmpHelperEQIyyEENS_15AssertionResultEPKcS4_RKT_RKT0_:
   0x00450afc <+0>:	push	{r4, r5, r6, r7, r8, r9, r10, r11, lr}
   0x00450b00 <+4>:	sub	sp, sp, #60	; 0x3c
   0x00450b04 <+8>:	ldr	r5, [sp, #96]	; 0x60
=> 0x00450b08 <+12>:	ldm	r3, {r4, r7}
   0x00450b0c <+16>:	ldm	r5, {r6, r9}
   0x00450b10 <+20>:	eor	r7, r7, r9
   0x00450b14 <+24>:	eor	r6, r4, r6
   0x00450b18 <+28>:	orrs	r7, r6, r7

(gdb) p/x r3
$3 = 0x3e300f6e

"However, load and store multiple instructions (LDM and STM) and load and store double-word (LDRD or STRD) must be aligned to at least a word boundary."

https://developer.arm.com/documentation/den0013/d/Porting/Alignment

>>> 0x3e300f6e % 4
2

Program received signal SIGBUS, Bus error.
0x00450b08 in testing::AssertionResult testing::internal::CmpHelperEQ<unsigned long long, unsigned long long>(char const*, char const*, unsigned long long const&, unsigned long long const&) ()

The struct is packed with 1 byte alignment, but it needs to start at an aligned address for us
to ldm from it. So I've done that with alignas.

Also fixed some compiler warnings in the test itself.
adamfidel pushed a commit to adamfidel/llvm that referenced this pull request Feb 9, 2026
…ling (intel#318)

* [SYCL][Graph] Add e2e test checking profiling info

Adds an e2e test that checks the profiling info from an event returned by a graph submission.

Closes Issue: intel#96

* [SYCL][Graph] Update the implementation to support Profiling on graph execution

Sycl event impl object contains a flag indicating that this event results from a graph submission.
This flag was not set for every type of graph sumbission. This commit fixes this bug.
Adds a extra event in the first command list associated to the CommandBuffer execution to obtain the start time of the graph execution.
Modifies the urEventGetProfilingInfo function to get the CommandBuffer start time from this new event.
Improves to profiling e2e test.
Removes the test checking for exception throwing (unsupported feature).

* [SYCL][Graph] Add resync of submit time to start time if time shift

* [SYCL][Graph] Adds condition on queue prop before adding the new profiling event to CL
adamfidel pushed a commit to adamfidel/llvm that referenced this pull request Feb 9, 2026
Checks the info::event_profiling query from an event returned by a graph submission.
Note that profiling is a queue property. It is therefore only available for the Record&Replay API.

Closes Issue: intel#96
iclsrc pushed a commit that referenced this pull request Apr 23, 2026
A function like 

```llvm
define <4 x i16> @xtn_shuffle_even_v8i16(<8 x i16> %a) {
entry:
  %r = shufflevector <8 x i16> %a, <8 x i16> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
  ret <4 x i16> %r
}
```

will use the `xtn` instruction, which for each 32-bit vector element
keeps only the lower 16 bits, so effectively this is a truncation.
However, if the vector actually has 16-bit elements, then the conversion
from a shuffle to a truncation is only valid on LE, not on BE. On BE,
`uzp1` should be used instead. So this PR moves some logic to right
after a check for LE, so that BE does not miscompile.

I filed this as an issue on `rust-lang-rust` as
rust-lang/rust#155459, and we had some
discussion at [#t-libs/stdarch > &#96;simd_shuffle!&#96; behaves
strangely on
&#96;aarch64_be&#96;](https://rust-lang.zulipchat.com/#narrow/channel/208962-t-libs.2Fstdarch/topic/.60simd_shuffle.21.60.20behaves.20strangely.20on.20.60aarch64_be.60/with/587766433).
iclsrc pushed a commit that referenced this pull request Jun 24, 2026
### Summary

On ARM/Thumb2, a saturating clamp to a signed range that is not centered
on zero is *not* matched to `ssat`, even though it can be potentially
matched to `ssat`. The backend instead emits a long explicit
compare/select clamp.

This pattern is extremely common in quantized ML code: an int8
requantize is `clamp(accumulator + output_zero_point, -128, 127)`, and
whenever the output zero_point != 0, the instruction count regress from
one ssat to ~10 instructions.

The root cause is that InstCombine canonically **sinks the constant out
of the min/max** — `clamp(X + C, -128, 127)` becomes `clamp(X, -128-C,
127-C) + C` — and the backend's SSAT matcher
(`PerformMinMaxToSatCombine`) only handles a clamp whose bounds already
form a saturation range. The offset of the form (`[-128-C, 127-C]`,
width 256 = 2⁸) falls through to a generic clamp.

#### Reproducer

```c
#include <stdint.h>
int8_t requant_offset(int32_t acc) {   // output zero-point = 96
    int32_t v = (acc >> 8) + 96;
    if (v < -128) v = -128;
    if (v >  127) v =  127;
    return (int8_t)v;
}
int8_t requant_zero(int32_t acc) {      // output zero-point = 0  (for contrast)
    int32_t v = (acc >> 8);
    if (v < -128) v = -128;
    if (v >  127) v =  127;
    return (int8_t)v;
}
```

```
clang -O2 --target=thumbv7em-none-eabihf -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -S issue.c
```

**Actual** 
`requant_offset` (zero-point 96):
```asm
asrs   r1, r0, #8
cmn.w  r1, #224
mvn    r1, #223
it     gt
asrgt  r1, r0, #8
cmp    r1, #31
it     ge
movge  r1, #31
add.w  r0, r1, #96
sxtb   r0, r0
```

`requant_zero` (zero-point 0):
```asm
ssat   r0, #8, r0, asr #8
```

#### Expected

`requant_offset` should select `ssat`, e.g.:
```asm
movs   r1, #96
add.w  r0, r1, r0, asr #8
ssat   r0, #8, r0
subs   r0, #96
```

#### Why this is sound

A clamp whose width (hi − lo + 1) is a power of two is just an `ssat`
shifted off zero by constant C.

```
clamp(X, lo, hi) == ssat_k(X − C) + C,   C = lo + 2^(k-1)
```

e.g. `clamp(X, −224, 31)` == `clamp(X+96, (-225+96), (31+96)) - 96` ==
`ssat8(X + 96) − 96`

Assisted-by: Claude
wenju-he pushed a commit that referenced this pull request Jun 26, 2026
### Summary

On ARM/Thumb2, a saturating clamp to a signed range that is not centered
on zero is *not* matched to `ssat`, even though it can be potentially
matched to `ssat`. The backend instead emits a long explicit
compare/select clamp.

This pattern is extremely common in quantized ML code: an int8
requantize is `clamp(accumulator + output_zero_point, -128, 127)`, and
whenever the output zero_point != 0, the instruction count regress from
one ssat to ~10 instructions.

The root cause is that InstCombine canonically **sinks the constant out
of the min/max** — `clamp(X + C, -128, 127)` becomes `clamp(X, -128-C,
127-C) + C` — and the backend's SSAT matcher
(`PerformMinMaxToSatCombine`) only handles a clamp whose bounds already
form a saturation range. The offset of the form (`[-128-C, 127-C]`,
width 256 = 2⁸) falls through to a generic clamp.

#### Reproducer

```c
#include <stdint.h>
int8_t requant_offset(int32_t acc) {   // output zero-point = 96
    int32_t v = (acc >> 8) + 96;
    if (v < -128) v = -128;
    if (v >  127) v =  127;
    return (int8_t)v;
}
int8_t requant_zero(int32_t acc) {      // output zero-point = 0  (for contrast)
    int32_t v = (acc >> 8);
    if (v < -128) v = -128;
    if (v >  127) v =  127;
    return (int8_t)v;
}
```

```
clang -O2 --target=thumbv7em-none-eabihf -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -S issue.c
```

**Actual** 
`requant_offset` (zero-point 96):
```asm
asrs   r1, r0, #8
cmn.w  r1, #224
mvn    r1, #223
it     gt
asrgt  r1, r0, #8
cmp    r1, #31
it     ge
movge  r1, #31
add.w  r0, r1, #96
sxtb   r0, r0
```

`requant_zero` (zero-point 0):
```asm
ssat   r0, #8, r0, asr #8
```

#### Expected

`requant_offset` should select `ssat`, e.g.:
```asm
movs   r1, #96
add.w  r0, r1, r0, asr #8
ssat   r0, #8, r0
subs   r0, #96
```

#### Why this is sound

A clamp whose width (hi − lo + 1) is a power of two is just an `ssat`
shifted off zero by constant C.

```
clamp(X, lo, hi) == ssat_k(X − C) + C,   C = lo + 2^(k-1)
```

e.g. `clamp(X, −224, 31)` == `clamp(X+96, (-225+96), (31+96)) - 96` ==
`ssat8(X + 96) − 96`

Assisted-by: Claude
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants