Bug 514876

Summary: x86: Handle F32 Iex_ITE expression
Product: [Developer tools] valgrind Reporter: Mark Harris <mark.hsj>
Component: vexAssignee: Paul Floyd <pjfloyd>
Status: REPORTED ---    
Severity: normal CC: pjfloyd
Priority: NOR    
Version First Reported In: 3.27 GIT   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:
Attachments: Patch to correct the issue
Source file to reproduce the issue
main on FreeBSD
Linux objdump

Description Mark Harris 2026-01-20 19:49:22 UTC
SUMMARY
Running a 32-bit x86 Linux binary under valgrind produces a fatal error:

ITE(t69,t31,GET:F32(160))
vex: the `impossible' happened:
   iselFltExpr_wrk

STEPS TO REPRODUCE
1. Using clang 21.1.6, compile the attached source file for 32-bit x86 with -O: `clang -g -O -m32 bug-vgx86f32ite.c` (The issue does not occur when compiled with gcc 15.2.1.)
2. valgrind ./a.out
3. Valgrind produces a fatal error

OBSERVED RESULT
==1334040== Memcheck, a memory error detector
==1334040== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==1334040== Using Valgrind-3.26.0 and LibVEX; rerun with -h for copyright info
==1334040== Command: ./a.out
==1334040== 
ITE(t69,t31,GET:F32(160))
vex: the `impossible' happened:
   iselFltExpr_wrk
vex storage: T total 102182960 bytes allocated
vex storage: P total 496 bytes allocated

valgrind: the 'impossible' happened:
   LibVEX called failure_exit().

host stacktrace:
==1334040==    at 0x5803D665: show_sched_status_wrk (m_libcassert.c:426)
==1334040==    by 0x5803D7C0: report_and_quit (m_libcassert.c:497)
==1334040==    by 0x5803D941: panic (m_libcassert.c:572)
==1334040==    by 0x5803D941: vgPlain_core_panic_at (m_libcassert.c:577)
==1334040==    by 0x5803D95A: vgPlain_core_panic (m_libcassert.c:582)
==1334040==    by 0x5805363C: failure_exit (m_translate.c:761)
==1334040==    by 0x5815A6A3: vpanic (main_util.c:253)
==1334040==    by 0x581C075E: iselFltExpr_wrk (host_x86_isel.c:3037)
==1334040==    by 0x581C075E: iselFltExpr (host_x86_isel.c:2953)
==1334040==    by 0x581C150F: iselStmt (host_x86_isel.c:4096)
==1334040==    by 0x581C150F: iselSB_X86 (host_x86_isel.c:4640)
==1334040==    by 0x581581A4: libvex_BackEnd (main_main.c:1157)
==1334040==    by 0x581581A4: LibVEX_Translate (main_main.c:1294)
==1334040==    by 0x58055F5F: vgPlain_translate (m_translate.c:1835)
==1334040==    by 0x580982D8: handle_chain_me (scheduler.c:1172)
==1334040==    by 0x5809AC42: vgPlain_scheduler (scheduler.c:1568)
==1334040==    by 0x5810490E: thread_wrapper (syswrap-linux.c:102)
==1334040==    by 0x5810490E: run_a_thread_NORETURN (syswrap-linux.c:154)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 1334040)
==1334040==    at 0x400128C: main (vgmoc.c:14)
client stack range: [0xFEFFB000 0xFEFFDFFF] client SP: 0xFEFFD970
valgrind stack range: [0x82E82000 0x82F81FFF] top usage: 9420 of 1048576


Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using.  Thanks.

EXPECTED RESULT
Valgrind is expected to complete successfully.

SOFTWARE/OS VERSIONS
The issue occurs with Valgrind 3.26.0 and with current git master.
Linux 6.18.2, glibc 2.42.
Comment 1 Mark Harris 2026-01-20 19:52:51 UTC
Created attachment 188723 [details]
Patch to correct the issue
Comment 2 Mark Harris 2026-01-20 19:56:00 UTC
Created attachment 188724 [details]
Source file to reproduce the issue
Comment 3 Paul Floyd 2026-01-21 07:42:33 UTC
Created attachment 188741 [details]
main on FreeBSD

I don't see the problem on FreeBSD with clang-devel (22.0.0git). Here is the output of objdump --disassemble-symbols=main
Comment 4 Paul Floyd 2026-01-21 07:52:27 UTC
Created attachment 188742 [details]
Linux objdump

On Linux clang is defaulting to some form of SSE rather than x87.
Comment 5 Paul Floyd 2026-01-21 07:53:02 UTC
I can reproduce on Fedora 43, clang 21.1.8.
Comment 6 Paul Floyd 2026-01-24 08:36:59 UTC
On FreeBSD clang -m32 -msse2 -mfpmath=sse  ./bug514876.c -o ./bug514876 -lm generates SSE but still does not reproduce the error. Need to diff the asm and check if it is really SSE2.
Comment 7 Mark Harris 2026-01-24 18:21:54 UTC
(In reply to Paul Floyd from comment #6)
> On FreeBSD clang -m32 -msse2 -mfpmath=sse  ./bug514876.c -o ./bug514876 -lm
> generates SSE but still does not reproduce the error.

I don't have a FreeBSD machine to try, but at least on Linux it requires -O or -O2; it does not reproduce without optimization.
Comment 8 Paul Floyd 2026-01-24 19:34:38 UTC
Sorry , yes, I can only reproduce with -O, I'll try that again.

I have no problem with --vex-guest-chase=no

On Linux the problem is in this section of code

        a = sin(sqrt(i));
 804839a:       0f 57 d2                xorps  %xmm2,%xmm2
 804839d:       f2 0f 2a d6             cvtsi2sd %esi,%xmm2
 80483a1:       0f 57 c9                xorps  %xmm1,%xmm1
 80483a4:       f2 0f 51 ca             sqrtsd %xmm2,%xmm1
 80483a8:       66 0f 57 c0             xorpd  %xmm0,%xmm0
 80483ac:       f2 0f 11 54 24 20       movsd  %xmm2,0x20(%esp)
 80483b2:       66 0f 2e d0             ucomisd %xmm0,%xmm2
 80483b6:       f2 0f 11 4c 24 30       movsd  %xmm1,0x30(%esp)
 80483bc:       66 0f 28 c1             movapd %xmm1,%xmm0
 80483c0:       73 1a                   jae    80483dc <main+0x5c>
 80483c2:       f2 0f 10 44 24 20       movsd  0x20(%esp),%xmm0
 80483c8:       f2 0f 11 04 24          movsd  %xmm0,(%esp)
 80483cd:       e8 3e fe ff ff          call   8048210 <sqrt@plt>
 80483d2:       dd 5c 24 40             fstpl  0x40(%esp)
 80483d6:       f2 0f 10 44 24 40       movsd  0x40(%esp),%xmm0
 80483dc:       f2 0f 11 04 24          movsd  %xmm0,(%esp)
 80483e1:       e8 5a fe ff ff          call   8048240 <sin@plt>
 80483e6:       d9 5c 24 2c             fstps  0x2c(%esp)
 80483ea:       f3 0f 10 54 24 2c       movss  0x2c(%esp),%xmm2

where the jae causes the problem. As I understand that it does

1. speculative sqrt op-code (onlu valid for
2. checks the arg is >= 0
3. if it is, jump around next block
4. if it is < 0 call libm sqrt
Comment 9 Paul Floyd 2026-01-24 20:19:30 UTC
I can reproduce with clang 19 and -O on FreeBSD, but not with clang22.

I need to write a reproducer in assembler since triggering this from C seems complicated.