From da918bcdd32323f37b38432fb11502a8cdc91412 Mon Sep 17 00:00:00 2001 From: omsherikar Date: Thu, 6 Nov 2025 19:24:02 +0530 Subject: [PATCH 1/7] fix: set module triple/data layout; drop forced 64-bit size_t override --- src/irx/builders/llvmliteir.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/irx/builders/llvmliteir.py b/src/irx/builders/llvmliteir.py index 7f1e582..f34dd13 100644 --- a/src/irx/builders/llvmliteir.py +++ b/src/irx/builders/llvmliteir.py @@ -173,6 +173,15 @@ def __init__(self) -> None: codemodel="small" ) + # Attach target triple and data layout to the module for correct sizes/ABI + try: + self._llvm.module.triple = self.target.triple # type: ignore[attr-defined] + except Exception: + # Fallback to the default triple if attribute not available + self._llvm.module.triple = llvm.get_default_triple() + # target_data prints to a canonical data layout string + self._llvm.module.data_layout = str(self.target_machine.target_data) + self._add_builtins() def translate(self, node: astx.AST) -> str: @@ -240,8 +249,8 @@ def initialize(self) -> None: self._llvm.INT32_TYPE, ] ) - # Platform-sized unsigned integer (assume 64-bit for CI targets) - self._llvm.SIZE_T_TYPE = ir.IntType(64) + # SIZE_T_TYPE already initialized based on host; do not override with a + # fixed width here to avoid mismatches on non-64-bit targets. def _add_builtins(self) -> None: # The C++ tutorial adds putchard() simply by defining it in the host From 5c2ccde446d1e24d154dfdee3ebae357eff617d4 Mon Sep 17 00:00:00 2001 From: omsherikar Date: Thu, 6 Nov 2025 23:34:06 +0530 Subject: [PATCH 2/7] fix: initialize SIZE_T_TYPE from target machine --- src/irx/builders/llvmliteir.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/irx/builders/llvmliteir.py b/src/irx/builders/llvmliteir.py index f34dd13..86e2a49 100644 --- a/src/irx/builders/llvmliteir.py +++ b/src/irx/builders/llvmliteir.py @@ -4,6 +4,7 @@ import ctypes import os +import re import tempfile from datetime import datetime @@ -173,15 +174,20 @@ def __init__(self) -> None: codemodel="small" ) - # Attach target triple and data layout to the module for correct sizes/ABI - try: - self._llvm.module.triple = self.target.triple # type: ignore[attr-defined] - except Exception: - # Fallback to the default triple if attribute not available - self._llvm.module.triple = llvm.get_default_triple() - # target_data prints to a canonical data layout string + self._llvm.module.triple = self.target_machine.triple self._llvm.module.data_layout = str(self.target_machine.target_data) + if self._llvm.SIZE_T_TYPE is None: + dl_str = str(self.target_machine.target_data) + ptr_match = re.search(r"p(?:\d+)?:(\d+)", dl_str) + if ptr_match: + ptr_bits = int(ptr_match.group(1)) + self._llvm.SIZE_T_TYPE = ir.IntType(ptr_bits) + else: + self._llvm.SIZE_T_TYPE = ir.IntType( + ctypes.sizeof(ctypes.c_size_t) * 8 + ) + self._add_builtins() def translate(self, node: astx.AST) -> str: @@ -192,7 +198,7 @@ def translate(self, node: astx.AST) -> str: def _init_native_size_types(self) -> None: """Initialize pointer/size_t types from host.""" self._llvm.POINTER_BITS = ctypes.sizeof(ctypes.c_void_p) * 8 - self._llvm.SIZE_T_TYPE = ir.IntType(ctypes.sizeof(ctypes.c_size_t) * 8) + self._llvm.SIZE_T_TYPE = None def initialize(self) -> None: """Initialize self.""" From 0a6848f4bfd578b8549674f558eb75cf35c65c26 Mon Sep 17 00:00:00 2001 From: omsherikar Date: Wed, 12 Nov 2025 22:42:20 +0530 Subject: [PATCH 3/7] fix: use LLVM API for SIZE_T_TYPE initialization --- src/irx/builders/llvmliteir.py | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/irx/builders/llvmliteir.py b/src/irx/builders/llvmliteir.py index 86e2a49..96bfc12 100644 --- a/src/irx/builders/llvmliteir.py +++ b/src/irx/builders/llvmliteir.py @@ -4,7 +4,6 @@ import ctypes import os -import re import tempfile from datetime import datetime @@ -178,15 +177,7 @@ def __init__(self) -> None: self._llvm.module.data_layout = str(self.target_machine.target_data) if self._llvm.SIZE_T_TYPE is None: - dl_str = str(self.target_machine.target_data) - ptr_match = re.search(r"p(?:\d+)?:(\d+)", dl_str) - if ptr_match: - ptr_bits = int(ptr_match.group(1)) - self._llvm.SIZE_T_TYPE = ir.IntType(ptr_bits) - else: - self._llvm.SIZE_T_TYPE = ir.IntType( - ctypes.sizeof(ctypes.c_size_t) * 8 - ) + self._llvm.SIZE_T_TYPE = self._get_size_t_type_from_triple() self._add_builtins() @@ -200,6 +191,29 @@ def _init_native_size_types(self) -> None: self._llvm.POINTER_BITS = ctypes.sizeof(ctypes.c_void_p) * 8 self._llvm.SIZE_T_TYPE = None + def _get_size_t_type_from_triple(self) -> ir.IntType: + """Determine size_t type from target triple using LLVM API.""" + triple = self.target_machine.triple.lower() + + if any( + arch in triple + for arch in [ + "x86_64", + "amd64", + "aarch64", + "arm64", + "ppc64", + "mips64", + ] + ): + return ir.IntType(64) + elif any(arch in triple for arch in ["i386", "i686", "arm", "mips"]): + if "64" in triple: + return ir.IntType(64) + return ir.IntType(32) + + return ir.IntType(ctypes.sizeof(ctypes.c_size_t) * 8) + def initialize(self) -> None: """Initialize self.""" self._llvm = VariablesLLVM() From ab370872f02ed3e62b53492a3007af18a760f692 Mon Sep 17 00:00:00 2001 From: omsherikar Date: Wed, 12 Nov 2025 23:14:43 +0530 Subject: [PATCH 4/7] test: add coverage for SIZE_T_TYPE fallback and float conversions --- tests/test_llvmlite_helpers.py | 63 ++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/test_llvmlite_helpers.py b/tests/test_llvmlite_helpers.py index bb48cc7..0a3be75 100644 --- a/tests/test_llvmlite_helpers.py +++ b/tests/test_llvmlite_helpers.py @@ -2,6 +2,8 @@ from __future__ import annotations +from unittest.mock import Mock, patch + from typing import Any, cast from irx.builders.llvmliteir import ( @@ -10,6 +12,7 @@ splat_scalar, ) from llvmlite import ir +from llvmlite.ir import DoubleType, FloatType class _NoFmaBuilder: @@ -95,3 +98,63 @@ def test_emit_int_div_signed_and_unsigned() -> None: assert getattr(signed, "opname", "") == "sdiv" assert getattr(unsigned, "opname", "") == "udiv" + + +def test_get_size_t_type_from_triple_32bit() -> None: + """Test _get_size_t_type_from_triple for 32-bit architectures.""" + visitor = LLVMLiteIRVisitor() + + mock_tm = Mock() + mock_tm.triple = "i386-unknown-linux-gnu" + visitor.target_machine = mock_tm + + size_t_ty = visitor._get_size_t_type_from_triple() + assert size_t_ty.width == 32 + + +def test_get_size_t_type_from_triple_fallback() -> None: + """Test _get_size_t_type_from_triple fallback for unknown architectures.""" + visitor = LLVMLiteIRVisitor() + + mock_tm = Mock() + mock_tm.triple = "unknown-arch-unknown-os" + visitor.target_machine = mock_tm + + size_t_ty = visitor._get_size_t_type_from_triple() + assert isinstance(size_t_ty, ir.IntType) + assert size_t_ty.width in (32, 64) + + +def test_scalar_vector_float_conversion_fptrunc() -> None: + """Test scalar-vector promotion with float truncation.""" + visitor = LLVMLiteIRVisitor() + _prime_builder(visitor) + + double_ty = visitor._llvm.DOUBLE_TYPE + float_ty = visitor._llvm.FLOAT_TYPE + vec_ty = ir.VectorType(float_ty, 2) + + scalar = ir.Constant(double_ty, 3.14) + converted = visitor._llvm.ir_builder.fptrunc(scalar, float_ty, "test") + result = splat_scalar(visitor._llvm.ir_builder, converted, vec_ty) + + assert isinstance(result.type, ir.VectorType) + assert result.type.element == float_ty + + +def test_scalar_vector_float_conversion_fpext() -> None: + """Test scalar-vector promotion with float extension.""" + visitor = LLVMLiteIRVisitor() + _prime_builder(visitor) + + float_ty = visitor._llvm.FLOAT_TYPE + double_ty = visitor._llvm.DOUBLE_TYPE + vec_ty = ir.VectorType(double_ty, 2) + + scalar = ir.Constant(float_ty, 3.14) + + converted = visitor._llvm.ir_builder.fpext(scalar, double_ty, "test") + result = splat_scalar(visitor._llvm.ir_builder, converted, vec_ty) + + assert isinstance(result.type, ir.VectorType) + assert result.type.element == double_ty From 373dfacad13cd34c3ca949508293d82b60d50ad0 Mon Sep 17 00:00:00 2001 From: omsherikar Date: Wed, 12 Nov 2025 23:20:17 +0530 Subject: [PATCH 5/7] fix: suppress PLR2004 magic number warnings in tests --- tests/test_llvmlite_helpers.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/test_llvmlite_helpers.py b/tests/test_llvmlite_helpers.py index 0a3be75..939d273 100644 --- a/tests/test_llvmlite_helpers.py +++ b/tests/test_llvmlite_helpers.py @@ -2,9 +2,8 @@ from __future__ import annotations -from unittest.mock import Mock, patch - from typing import Any, cast +from unittest.mock import Mock from irx.builders.llvmliteir import ( LLVMLiteIRVisitor, @@ -12,7 +11,6 @@ splat_scalar, ) from llvmlite import ir -from llvmlite.ir import DoubleType, FloatType class _NoFmaBuilder: @@ -109,7 +107,7 @@ def test_get_size_t_type_from_triple_32bit() -> None: visitor.target_machine = mock_tm size_t_ty = visitor._get_size_t_type_from_triple() - assert size_t_ty.width == 32 + assert size_t_ty.width == 32 # noqa: PLR2004 def test_get_size_t_type_from_triple_fallback() -> None: From 06223e3a9cbf28668f22f0f0bf720f1e4756267c Mon Sep 17 00:00:00 2001 From: omsherikar Date: Wed, 12 Nov 2025 23:26:35 +0530 Subject: [PATCH 6/7] test: add coverage for SIZE_T_TYPE fallback and float conversions --- tests/test_llvmlite_helpers.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/test_llvmlite_helpers.py b/tests/test_llvmlite_helpers.py index 939d273..d746963 100644 --- a/tests/test_llvmlite_helpers.py +++ b/tests/test_llvmlite_helpers.py @@ -101,11 +101,11 @@ def test_emit_int_div_signed_and_unsigned() -> None: def test_get_size_t_type_from_triple_32bit() -> None: """Test _get_size_t_type_from_triple for 32-bit architectures.""" visitor = LLVMLiteIRVisitor() - + mock_tm = Mock() mock_tm.triple = "i386-unknown-linux-gnu" visitor.target_machine = mock_tm - + size_t_ty = visitor._get_size_t_type_from_triple() assert size_t_ty.width == 32 # noqa: PLR2004 @@ -113,11 +113,11 @@ def test_get_size_t_type_from_triple_32bit() -> None: def test_get_size_t_type_from_triple_fallback() -> None: """Test _get_size_t_type_from_triple fallback for unknown architectures.""" visitor = LLVMLiteIRVisitor() - + mock_tm = Mock() mock_tm.triple = "unknown-arch-unknown-os" visitor.target_machine = mock_tm - + size_t_ty = visitor._get_size_t_type_from_triple() assert isinstance(size_t_ty, ir.IntType) assert size_t_ty.width in (32, 64) @@ -127,15 +127,15 @@ def test_scalar_vector_float_conversion_fptrunc() -> None: """Test scalar-vector promotion with float truncation.""" visitor = LLVMLiteIRVisitor() _prime_builder(visitor) - + double_ty = visitor._llvm.DOUBLE_TYPE float_ty = visitor._llvm.FLOAT_TYPE vec_ty = ir.VectorType(float_ty, 2) - + scalar = ir.Constant(double_ty, 3.14) converted = visitor._llvm.ir_builder.fptrunc(scalar, float_ty, "test") result = splat_scalar(visitor._llvm.ir_builder, converted, vec_ty) - + assert isinstance(result.type, ir.VectorType) assert result.type.element == float_ty @@ -144,15 +144,15 @@ def test_scalar_vector_float_conversion_fpext() -> None: """Test scalar-vector promotion with float extension.""" visitor = LLVMLiteIRVisitor() _prime_builder(visitor) - + float_ty = visitor._llvm.FLOAT_TYPE double_ty = visitor._llvm.DOUBLE_TYPE vec_ty = ir.VectorType(double_ty, 2) - + scalar = ir.Constant(float_ty, 3.14) - + converted = visitor._llvm.ir_builder.fpext(scalar, double_ty, "test") result = splat_scalar(visitor._llvm.ir_builder, converted, vec_ty) - + assert isinstance(result.type, ir.VectorType) assert result.type.element == double_ty From f6768b8c8faa8e132d38d369abb8591b793b361d Mon Sep 17 00:00:00 2001 From: Ivan Ogasawara Date: Thu, 22 Jan 2026 23:07:56 +0000 Subject: [PATCH 7/7] fix issues with ruff --- tests/test_llvmlite_helpers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_llvmlite_helpers.py b/tests/test_llvmlite_helpers.py index 2ccba8f..2681add 100644 --- a/tests/test_llvmlite_helpers.py +++ b/tests/test_llvmlite_helpers.py @@ -97,6 +97,7 @@ def test_emit_int_div_signed_and_unsigned() -> None: assert getattr(signed, "opname", "") == "sdiv" assert getattr(unsigned, "opname", "") == "udiv" + def test_get_size_t_type_from_triple_32bit() -> None: """Test _get_size_t_type_from_triple for 32-bit architectures.""" visitor = LLVMLiteIRVisitor() @@ -156,6 +157,7 @@ def test_scalar_vector_float_conversion_fpext() -> None: assert isinstance(result.type, ir.VectorType) assert result.type.element == double_ty + def test_set_fast_math_marks_float_ops() -> None: """set_fast_math should add fast flag to floating instructions.""" visitor = LLVMLiteIRVisitor()