Skip to content

DPC++ device frontend never terminates on imgui_internal.h #22972

Description

@johguenther

Describe the bug

Just including imgui_internal.h (Dear ImGui v1.92.9b) spins "forever", 100% CPU, memory flat at 54 MB.

compiler
oneAPI 2025.1 / .2 / .3 ok ~1.5 s
v6.2.0 ok 0.9 s
v7.0.0 killed at 300 s
nightly-2026-08-17 killed at 90 s, i.e. not fixed upstream

To reproduce

git clone --depth 1 --branch v1.92.9b https://github.com/ocornut/imgui.git
echo '#include "imgui_internal.h"' > repro.cpp
clang++ -fsycl -fsycl-device-only -fsyntax-only -Iimgui repro.cpp

Device pass only. -fsycl-is-host and plain C++ 0.2 s, preprocessing unaffected.
Up to v7.0.0 one cc1 flag on the host triple suffices, no SYCL headers: clang++ -fsyntax-only -Xclang -fsycl-is-device -Iimgui repro.cpp.
Newer nightlies reject a non-SPIR-V triple there, so use -fsycl -fsycl-device-only for cross-version runs.

Including imgui.h alone is fine. Needs the dense mutually-referential graph of ImGuiContext/ImGuiWindow.

Attaching files failed, minimal self-contained (no #include) repro by reducing the header, ill-formed by design (-ferror-limit=0): 0.1 s v6.2.0 vs 2.0 s v7.0.0, 20x slowdown (not hanging):

typedef signed short ImS16;
typedef unsigned short ImU16;
typedef signed int ImS32;
typedef unsigned int ImU32;
typedef signed long long ImS64;
typedef unsigned long long ImU64;
struct ImDrawChannel;
struct ImDrawCmd;
struct ImDrawData;
struct ImDrawList;
struct ImDrawListSharedData;
struct ImDrawListSplitter;
struct ImDrawVert;
struct ImFont;
struct ImFontAtlas;
struct ImFontAtlasBuilder;
struct ImFontConfig;
struct ImFontGlyph;
struct ImFontGlyphRangesBuilder;
struct ImFontLoader;
struct ImTextureData;
struct ImTextureRect;
struct ImGuiSelectionExternalStorage;
struct ImGuiSelectionRequest;
struct ImGuiSizeCallbackData;
struct ImGuiStorage;
enum ImGuiDir : int;
enum ImGuiKey : int;
enum ImGuiMouseSource : int;
enum ImGuiSortDirection : ImU8;
typedef int ImGuiCol;
typedef int ImGuiListClipperFlags;
typedef unsigned short ImWchar16;
template <typename T> struct ImVector {
  int Size;
  int Capacity;
  T *Data;
  ImVec2 WindowTitleAlign;
  ImGuiDir WindowMenuButtonPosition;
  float ChildRounding;
  float ChildBorderSize;
  float PopupRounding;
  ImVec2 DisplayWindowPadding;
  ImVec2 DisplaySafeAreaPadding;
  float MouseCursorScale;
  bool AntiAliasedLines;
  bool AntiAliasedLinesUseTex;
  bool AntiAliasedFill;
  float CurveTessellationTol;
  float CircleTessellationMaxError;
  ImVec4 Colors[ImGuiCol_COUNT];
  float HoverStationaryDelay;
  float HoverDelayShort;
  float HoverDelayNormal;
  ImGuiHoveredFlags HoverFlagsForTooltipMouse;
  ImGuiHoveredFlags HoverFlagsForTooltipNav;
  ImFontAtlas *Fonts;
  ImFont *FontDefault;
  void SetStatus(ImTextureStatus status) {
    Status = status;
    if (status == ImTextureStatus_Destroyed && !WantDestroyNextFrame &&
        Pixels != nullptr)
      Status = ImTextureStatus_WantCreate;
  }
  ImFont *DstFont;
  const ImFontLoader *FontLoader;
  void *FontLoaderData;
  ImFontAtlasFlags_NoBakedLines = 1 << 2,
};
struct ImFontAtlas {
  ImFontAtlas();
  ~ImFontAtlas();
  ImFont *AddFont(const ImFontConfig *font_cfg);
  ImFont *AddFontDefault(const ImFontConfig *font_cfg = 0);
  ImVector<ImTextureData *> TexList;
  bool RendererHasTextures;
  bool TexIsBuilt;
  ImVec2 TexUvWhitePixel;
  ImVector<ImFont *> Fonts;
  ImVector<ImFontConfig> Sources;
  ImVec4 TexUvLines[(32) + 1];
  int TexNextUniqueID;
  int FontNextUniqueID;
  ImVector<ImDrawListSharedData *> DrawListSharedDatas;
  ImFontAtlasBuilder *Builder;
  const ImFontLoader *FontLoader;
  const char *FontLoaderName;
  void *FontLoaderData;
  int RefCount;
  ImGuiContext *OwnerContext;
  ImVector<float> IndexAdvanceX;
  float FallbackAdvanceX;
  float Size;
  float RasterizerDensity;
  ImVector<ImU16> IndexLookup;
  ImVector<ImFontGlyph> Glyphs;
  int FallbackGlyphIndex;
  float Ascent, Descent;
  unsigned int MetricsTotalSurface : 26;
  unsigned int WantDestroy : 1;
  unsigned int LoadNoFallback : 1;
  unsigned int LoadNoRenderOnLayout : 1;
  int LastUsedFrame;
  ImGuiID BakedId;
  ImFont *OwnerFont;
};
struct ImFont {
  ImFontBaked *LastBaked;
  ImFontAtlas *OwnerAtlas;
  ImFontFlags Flags;
  float CurrentRasterizerDensity;
  ImVector<ImFontConfig *> Sources;
}
}
;
struct ImRect {
  ImVec2 Min;
  ImVec2 Max;
  ImVector<ImVec2> TempBuffer;
  ImVector<ImDrawList *> DrawLists;
  ImVector<ImFontAtlas *> FontAtlases;
  ImFont *Font;
  ImVector<float> ItemWidthStack;
  ImVector<float> TextWrapPosStack;
};
struct ImGuiWindow {
  ImGuiWindowFlags Flags;
  ImRect OuterRectClipped;
  ImRect InnerRect;
  ImRect InnerClipRect;
  ImRect WorkRect;
  ImRect ParentWorkRect;
  ImRect ClipRect;
  ImGuiWindow *ParentWindow;
  ImGuiWindow *ParentWindowInBeginStack;
  ImGuiWindow *RootWindow;
  ImGuiWindow *RootWindowPopupTree;
};
ImGuiWindow *OuterWindow;

Environment

  • OS: independent
  • Target device and vendor: N/A, frontend only
  • DPC++ version: bisected
    last good: nightly-2025-09-24   3276ddd75dae5563f336737daddcbb151484702b
    first bad: nightly-2025-09-30   0ff1a5c2b4e4bc56799ec2dd17a89c3c57608890
    

Additional context

Hypothesis from Claude:

checkSYCLType() in clang/lib/Sema/SemaSYCL.cpp, from SemaSYCL::checkSYCLDeviceVarDecl, device mode only. Walks all fields, follows pointers/arrays into the pointee's fields. Visited passed by value => memoizes per DFS path, not globally => enumerates simple paths instead of visiting each type once. See #17313 (open, wants checkSYCLType merged into Sema::checkTypeSupport); mentions no perf impact, but same function.

Exponential in both versions: on v6.2.0, nesting struct W { ImGuiContext* a; ImGuiContext* b; };
N deep multiplies time by ~1.8/level (0.7, 0.9, 1.3, 2.0, 3.7 s). So not a new loop — something in the Sept 2025 window weakened dedup enough to push ImGui's graph past any usable threshold;
v6.2.0 needs ~9 extra doublings to reach v7.0.0.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions