llvmlite 0.43.0rc1__cp310-cp310-macosx_11_0_arm64.whl → 0.44.0rc2__cp310-cp310-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of llvmlite might be problematic. Click here for more details.

@@ -18,7 +18,8 @@ from llvmlite import binding as llvm
18
18
  from llvmlite.binding import ffi
19
19
  from llvmlite.tests import TestCase
20
20
 
21
- llvm_version_major = llvm.llvm_version_info[0]
21
+ # FIXME: Remove me once typed pointers are no longer supported.
22
+ from llvmlite import opaque_pointers_enabled
22
23
 
23
24
  # arvm7l needs extra ABI symbols to link successfully
24
25
  if platform.machine() == 'armv7l':
@@ -78,6 +79,16 @@ asm_sum3 = r"""
78
79
  }}
79
80
  """
80
81
 
82
+ asm_sum4 = r"""
83
+ ; ModuleID = '<string>'
84
+ target triple = "{triple}"
85
+
86
+ define i32 @sum(i32 %.1, i32 %.2) {{
87
+ %.3 = add i32 %.1, %.2
88
+ ret i32 0
89
+ }}
90
+ """
91
+
81
92
  asm_mul = r"""
82
93
  ; ModuleID = '<string>'
83
94
  target triple = "{triple}"
@@ -444,6 +455,26 @@ declare void @a_readonly_func(i8 *) readonly
444
455
  declare i8* @a_arg0_return_func(i8* returned, i32*)
445
456
  """
446
457
 
458
+ asm_alloca_optnone = r"""
459
+ define double @foo(i32 %i, double %j) optnone noinline {
460
+ %I = alloca i32 ; <i32*> [#uses=4]
461
+ %J = alloca double ; <double*> [#uses=2]
462
+ store i32 %i, i32* %I
463
+ store double %j, double* %J
464
+ %t1 = load i32, i32* %I ; <i32> [#uses=1]
465
+ %t2 = add i32 %t1, 1 ; <i32> [#uses=1]
466
+ store i32 %t2, i32* %I
467
+ %t3 = load i32, i32* %I ; <i32> [#uses=1]
468
+ %t4 = sitofp i32 %t3 to double ; <double> [#uses=1]
469
+ %t5 = load double, double* %J ; <double> [#uses=1]
470
+ %t6 = fmul double %t4, %t5 ; <double> [#uses=1]
471
+ ret double %t6
472
+ }
473
+ """
474
+
475
+ asm_declaration = r"""
476
+ declare void @test_declare(i32* )
477
+ """
447
478
 
448
479
  # This produces the following output from objdump:
449
480
  #
@@ -523,6 +554,102 @@ for.body:
523
554
  }}
524
555
  """
525
556
 
557
+ asm_cpp_class = r"""
558
+ ; Source C++
559
+ ;-----------------------------------------
560
+ ; class MyClass;
561
+ ;
562
+ ; class MyClassDefined{
563
+ ; MyClass *member;
564
+ ; MyClass *m2;
565
+ ; MyClass *m3;
566
+ ; };
567
+ ;
568
+ ; void foo(MyClass *c, MyClassDefined){ }
569
+ ;-----------------------------------------
570
+ ; LLVM-IR by: clang -arch arm64 -S -emit-llvm file.cpp
571
+ ; ModuleID = 'file.cpp'
572
+ source_filename = "class.cpp"
573
+ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
574
+ target triple = "arm64-apple-macosx13.3.0"
575
+
576
+ %class.MyClass = type opaque
577
+ %class.MyClassDefined = type { %class.MyClass*, %class.MyClass*, %class.MyClass* }
578
+
579
+ ; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
580
+ define void @_Z3fooP7MyClass14MyClassDefined(%class.MyClass* noundef %0, %class.MyClassDefined* noundef %1) {
581
+ %3 = alloca %class.MyClass*, align 8
582
+ store %class.MyClass* %0, %class.MyClass** %3, align 8
583
+ ret void
584
+ }
585
+
586
+ !llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
587
+ !llvm.ident = !{!9}
588
+
589
+ !0 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 3]}
590
+ !1 = !{i32 1, !"wchar_size", i32 4}
591
+ !2 = !{i32 8, !"branch-target-enforcement", i32 0}
592
+ !3 = !{i32 8, !"sign-return-address", i32 0}
593
+ !4 = !{i32 8, !"sign-return-address-all", i32 0}
594
+ !5 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
595
+ !6 = !{i32 7, !"PIC Level", i32 2}
596
+ !7 = !{i32 7, !"uwtable", i32 1}
597
+ !8 = !{i32 7, !"frame-pointer", i32 1}
598
+ !9 = !{!"Apple clang version 14.0.3 (clang-1403.0.22.14.1)"}
599
+
600
+ """ # noqa
601
+
602
+ asm_cpp_vector = r"""; Source C++
603
+ ;-----------------------------------------
604
+
605
+ ; struct Vector2D{
606
+ ; float x, y;
607
+ ; };
608
+ ;
609
+ ; void foo(Vector2D vec, Vector2D *out) {
610
+ ; *out = vec;
611
+ ; }
612
+ ;-----------------------------------------
613
+ ; LLVM-IR by: clang -arch x86_64 -S -emit-llvm file.cpp
614
+ ; ModuleID = 'file.cpp'
615
+ source_filename = "class.cpp"
616
+ target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
617
+ target triple = "x86_64-apple-macosx13.3.0"
618
+
619
+ %struct.Vector2D = type { float, float }
620
+
621
+ ; Function Attrs: noinline nounwind optnone ssp uwtable
622
+ define void @_Z3foo8Vector2DPS_(<2 x float> %0, %struct.Vector2D* noundef %1) #0 {
623
+ %3 = alloca %struct.Vector2D, align 4
624
+ %4 = alloca %struct.Vector2D*, align 8
625
+ %5 = bitcast %struct.Vector2D* %3 to <2 x float>*
626
+ store <2 x float> %0, <2 x float>* %5, align 4
627
+ store %struct.Vector2D* %1, %struct.Vector2D** %4, align 8
628
+ %6 = load %struct.Vector2D*, %struct.Vector2D** %4, align 8
629
+ %7 = bitcast %struct.Vector2D* %6 to i8*
630
+ %8 = bitcast %struct.Vector2D* %3 to i8*
631
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %7, i8* align 4 %8, i64 8, i1 false)
632
+ ret void
633
+ }
634
+
635
+ ; Function Attrs: argmemonly nofree nounwind willreturn
636
+ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #1
637
+
638
+ attributes #0 = { noinline nounwind optnone ssp uwtable "darwin-stkchk-strong-link" "frame-pointer"="all" "min-legal-vector-width"="64" "no-trapping-math"="true" "probe-stack"="___chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
639
+ attributes #1 = { argmemonly nofree nounwind willreturn }
640
+
641
+ !llvm.module.flags = !{!0, !1, !2, !3, !4}
642
+ !llvm.ident = !{!5}
643
+
644
+ !0 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 3]}
645
+ !1 = !{i32 1, !"wchar_size", i32 4}
646
+ !2 = !{i32 7, !"PIC Level", i32 2}
647
+ !3 = !{i32 7, !"uwtable", i32 2}
648
+ !4 = !{i32 7, !"frame-pointer", i32 2}
649
+ !5 = !{!"Apple clang version 14.0.3 (clang-1403.0.22.14.1)"}
650
+
651
+ """ # noqa
652
+
526
653
 
527
654
  class BaseTest(TestCase):
528
655
 
@@ -787,7 +914,7 @@ class TestMisc(BaseTest):
787
914
  def test_version(self):
788
915
  major, minor, patch = llvm.llvm_version_info
789
916
  # one of these can be valid
790
- valid = (14, 15)
917
+ valid = (15, 16)
791
918
  self.assertIn(major, valid)
792
919
  self.assertIn(patch, range(8))
793
920
 
@@ -986,13 +1113,9 @@ class TestModuleRef(BaseTest):
986
1113
  with self.assertRaises(RuntimeError) as cm:
987
1114
  llvm.parse_bitcode(b"")
988
1115
  self.assertIn("LLVM bitcode parsing error", str(cm.exception))
989
- # for llvm < 9
990
- if llvm.llvm_version_info[0] < 9:
991
- self.assertIn("Invalid bitcode signature", str(cm.exception))
992
- else:
993
- self.assertIn(
994
- "file too small to contain bitcode header", str(cm.exception),
995
- )
1116
+ self.assertIn(
1117
+ "file too small to contain bitcode header", str(cm.exception),
1118
+ )
996
1119
 
997
1120
  def test_bitcode_roundtrip(self):
998
1121
  # create a new context to avoid struct renaming
@@ -1116,14 +1239,14 @@ class JITTestMixin(object):
1116
1239
  for g in (gv_i32, gv_i8, gv_struct):
1117
1240
  self.assertEqual(td.get_abi_size(g.type), pointer_size)
1118
1241
 
1119
- self.assertEqual(td.get_pointee_abi_size(gv_i32.type), 4)
1120
- self.assertEqual(td.get_pointee_abi_alignment(gv_i32.type), 4)
1242
+ self.assertEqual(td.get_abi_size(gv_i32.global_value_type), 4)
1243
+ self.assertEqual(td.get_abi_alignment(gv_i32.global_value_type), 4)
1121
1244
 
1122
- self.assertEqual(td.get_pointee_abi_size(gv_i8.type), 1)
1123
- self.assertIn(td.get_pointee_abi_alignment(gv_i8.type), (1, 2, 4))
1245
+ self.assertEqual(td.get_abi_size(gv_i8.global_value_type), 1)
1246
+ self.assertIn(td.get_abi_alignment(gv_i8.global_value_type), (1, 2, 4))
1124
1247
 
1125
- self.assertEqual(td.get_pointee_abi_size(gv_struct.type), 24)
1126
- self.assertIn(td.get_pointee_abi_alignment(gv_struct.type), (4, 8))
1248
+ self.assertEqual(td.get_abi_size(gv_struct.global_value_type), 24)
1249
+ self.assertIn(td.get_abi_alignment(gv_struct.global_value_type), (4, 8))
1127
1250
 
1128
1251
  def test_object_cache_notify(self):
1129
1252
  notifies = []
@@ -1507,28 +1630,32 @@ class TestValueRef(BaseTest):
1507
1630
  self.assertEqual(tp.name, "")
1508
1631
  st = mod.get_global_variable("glob_struct")
1509
1632
  self.assertIsNotNone(re.match(r"struct\.glob_type(\.[\d]+)?",
1510
- st.type.element_type.name))
1633
+ st.global_value_type.name))
1511
1634
 
1512
1635
  def test_type_printing_variable(self):
1513
1636
  mod = self.module()
1514
1637
  glob = mod.get_global_variable("glob")
1515
- tp = glob.type
1516
- self.assertEqual(str(tp), 'i32*')
1638
+ tp = glob.global_value_type
1639
+ self.assertEqual(str(tp), 'i32')
1517
1640
 
1518
1641
  def test_type_printing_function(self):
1519
1642
  mod = self.module()
1520
1643
  fn = mod.get_function("sum")
1521
- self.assertEqual(str(fn.type), "i32 (i32, i32)*")
1644
+ self.assertEqual(str(fn.global_value_type), "i32 (i32, i32)")
1522
1645
 
1523
1646
  def test_type_printing_struct(self):
1524
1647
  mod = self.module()
1525
1648
  st = mod.get_global_variable("glob_struct")
1526
1649
  self.assertTrue(st.type.is_pointer)
1527
- self.assertIsNotNone(re.match(r'%struct\.glob_type(\.[\d]+)?\*',
1528
- str(st.type)))
1650
+ # FIXME: Remove `else' once TP are no longer supported.
1651
+ if opaque_pointers_enabled:
1652
+ self.assertIsNotNone(re.match(r'ptr', str(st.type)))
1653
+ else:
1654
+ self.assertIsNotNone(re.match(r'%struct\.glob_type(\.[\d]+)?\*',
1655
+ str(st.type)))
1529
1656
  self.assertIsNotNone(re.match(
1530
1657
  r"%struct\.glob_type(\.[\d]+)? = type { i64, \[2 x i64\] }",
1531
- str(st.type.element_type)))
1658
+ str(st.global_value_type)))
1532
1659
 
1533
1660
  def test_close(self):
1534
1661
  glob = self.glob()
@@ -1613,11 +1740,13 @@ class TestValueRef(BaseTest):
1613
1740
  self.assertEqual(str(operands[1].type), 'i32')
1614
1741
 
1615
1742
  def test_function_attributes(self):
1743
+ ver = llvm.llvm_version_info[0]
1744
+ readonly_attrs = [b'memory(read)' if ver == 16 else b'readonly']
1616
1745
  mod = self.module(asm_attributes)
1617
1746
  for func in mod.functions:
1618
1747
  attrs = list(func.attributes)
1619
1748
  if func.name == 'a_readonly_func':
1620
- self.assertEqual(attrs, [b'readonly'])
1749
+ self.assertEqual(attrs, readonly_attrs)
1621
1750
  elif func.name == 'a_arg0_return_func':
1622
1751
  self.assertEqual(attrs, [])
1623
1752
  args = list(func.arguments)
@@ -1712,7 +1841,11 @@ class TestValueRef(BaseTest):
1712
1841
  inst = list(list(func.blocks)[0].instructions)[0]
1713
1842
  arg = list(inst.operands)[0]
1714
1843
  self.assertTrue(arg.is_constant)
1715
- self.assertEqual(arg.get_constant_value(), 'i64* null')
1844
+ # FIXME: Remove `else' once TP are no longer supported.
1845
+ if opaque_pointers_enabled:
1846
+ self.assertEqual(arg.get_constant_value(), 'ptr null')
1847
+ else:
1848
+ self.assertEqual(arg.get_constant_value(), 'i64* null')
1716
1849
 
1717
1850
  def test_incoming_phi_blocks(self):
1718
1851
  mod = self.module(asm_phi_blocks)
@@ -1741,7 +1874,7 @@ class TestTypeRef(BaseTest):
1741
1874
  def test_str(self):
1742
1875
  mod = self.module()
1743
1876
  glob = mod.get_global_variable("glob")
1744
- self.assertEqual(str(glob.type), "i32*")
1877
+ self.assertEqual(str(glob.global_value_type), "i32")
1745
1878
  glob_struct_type = mod.get_struct_type("struct.glob_type")
1746
1879
  self.assertEqual(str(glob_struct_type),
1747
1880
  "%struct.glob_type = type { i64, [2 x i64] }")
@@ -1761,7 +1894,7 @@ class TestTypeRef(BaseTest):
1761
1894
  self.assertEqual(glob_struct.type.type_kind, llvm.TypeKind.pointer)
1762
1895
  self.assertTrue(glob_struct.type.is_pointer)
1763
1896
 
1764
- stype = next(iter(glob_struct.type.elements))
1897
+ stype = glob_struct.global_value_type
1765
1898
  self.assertEqual(stype.type_kind, llvm.TypeKind.struct)
1766
1899
  self.assertTrue(stype.is_struct)
1767
1900
 
@@ -1777,7 +1910,7 @@ class TestTypeRef(BaseTest):
1777
1910
 
1778
1911
  funcptr = mod.get_function("sum").type
1779
1912
  self.assertEqual(funcptr.type_kind, llvm.TypeKind.pointer)
1780
- functype, = funcptr.elements
1913
+ functype = mod.get_function("sum").global_value_type
1781
1914
  self.assertEqual(functype.type_kind, llvm.TypeKind.function)
1782
1915
 
1783
1916
  def test_element_count(self):
@@ -1805,20 +1938,186 @@ class TestTypeRef(BaseTest):
1805
1938
  # Variadic function
1806
1939
  mod = self.module(asm_vararg_declare)
1807
1940
  func = mod.get_function('vararg')
1808
- decltype = func.type.element_type
1941
+ decltype = func.global_value_type
1809
1942
  self.assertTrue(decltype.is_function_vararg)
1810
1943
 
1811
1944
  mod = self.module(asm_sum_declare)
1812
1945
  func = mod.get_function('sum')
1813
- decltype = func.type.element_type
1946
+ decltype = func.global_value_type
1814
1947
  self.assertFalse(decltype.is_function_vararg)
1815
1948
 
1816
1949
  # test that the function pointer type cannot use is_function_vararg
1817
1950
  self.assertTrue(func.type.is_pointer)
1818
1951
  with self.assertRaises(ValueError) as raises:
1819
1952
  func.type.is_function_vararg
1820
- self.assertIn("Type i32 (i32, i32)* is not a function",
1821
- str(raises.exception))
1953
+ # FIXME: Remove `else' once TP are no longer supported.
1954
+ if opaque_pointers_enabled:
1955
+ self.assertIn("Type ptr is not a function", str(raises.exception))
1956
+ else:
1957
+ self.assertIn("Type i32 (i32, i32)* is not a function",
1958
+ str(raises.exception))
1959
+
1960
+ def test_function_typeref_as_ir(self):
1961
+ mod = self.module()
1962
+
1963
+ [fn] = list(mod.functions)
1964
+ # .type gives a pointer type, a problem if it's opaque (llvm15+)
1965
+ self.assertEqual(fn.type.type_kind, llvm.TypeKind.pointer)
1966
+ self.assertFalse(fn.type.is_function)
1967
+ # Use .global_value_type instead
1968
+ fnty = fn.global_value_type
1969
+ self.assertEqual(fnty.type_kind, llvm.TypeKind.function)
1970
+ self.assertTrue(fnty.is_function)
1971
+ # Run .as_ir() to get llvmlite.ir.FunctionType
1972
+ tyir = fnty.as_ir(ir.global_context)
1973
+ self.assertIsInstance(tyir, ir.FunctionType)
1974
+ self.assertEqual(tyir.args, (ir.IntType(32), ir.IntType(32)))
1975
+ self.assertEqual(tyir.return_type ,ir.IntType(32))
1976
+
1977
+ def test_void_typeref_as_ir(self):
1978
+ # Void type can only be used as return-type of llvmlite.ir.FunctionType.
1979
+ fnty = ir.FunctionType(ir.VoidType(), ())
1980
+ irmod = ir.Module()
1981
+ fn = ir.Function(irmod, fnty, "foo")
1982
+ mod = self.module(str(irmod))
1983
+ fn = mod.get_function("foo")
1984
+ gvty = fn.global_value_type
1985
+ self.assertEqual(fnty.return_type,
1986
+ gvty.as_ir(ir.global_context).return_type)
1987
+
1988
+ def test_global_typeref_as_ir(self):
1989
+ from llvmlite.binding.typeref import _TypeKindToIRType
1990
+ ctx = ir.Context()
1991
+
1992
+ skipped = {
1993
+ "function", # tested in test_function_typeref_as_ir
1994
+ "void", # tested in test_void_typeref_as_ir
1995
+ }
1996
+
1997
+ makers = {}
1998
+
1999
+ def maker_half():
2000
+ yield ir.HalfType()
2001
+
2002
+ makers['half'] = maker_half
2003
+
2004
+ def maker_float():
2005
+ yield ir.FloatType()
2006
+
2007
+ makers['float'] = maker_float
2008
+
2009
+ def maker_double():
2010
+ yield ir.DoubleType()
2011
+
2012
+ makers['double'] = maker_double
2013
+
2014
+ def maker_integer():
2015
+ yield ir.IntType(32)
2016
+
2017
+ makers['integer'] = maker_integer
2018
+
2019
+ def maker_pointer():
2020
+ yield ir.PointerType(ir.IntType(8))
2021
+ # opaque struct ptr
2022
+ yield ctx.get_identified_type("myclass").as_pointer()
2023
+ # named struct with defined body
2024
+ myclass2 = ctx.get_identified_type("myclass2")
2025
+ myclass2.set_body(ir.IntType(8))
2026
+ yield myclass2.as_pointer()
2027
+
2028
+ makers['pointer'] = maker_pointer
2029
+
2030
+ def maker_array():
2031
+ yield ir.ArrayType(ir.IntType(8), 123)
2032
+
2033
+ makers['array'] = maker_array
2034
+
2035
+ def maker_vector():
2036
+ yield ir.VectorType(ir.FloatType(), 2)
2037
+
2038
+ makers['vector'] = maker_vector
2039
+
2040
+ def maker_struct():
2041
+ yield ir.LiteralStructType([ir.FloatType(), ir.IntType(64)])
2042
+ yield ir.LiteralStructType([ir.FloatType(), ir.IntType(64)],
2043
+ packed=True)
2044
+
2045
+ makers['struct'] = maker_struct
2046
+
2047
+ # Ensure that number of supported TypeKind matches number of makers
2048
+ self.assertEqual({x.name for x in _TypeKindToIRType.keys()},
2049
+ set(makers.keys()) | set(skipped))
2050
+
2051
+ # Test each type-kind
2052
+ for type_kind, irtype in _TypeKindToIRType.items():
2053
+ if type_kind.name in skipped:
2054
+ continue
2055
+ for ty in makers[type_kind.name]():
2056
+ with self.subTest(f"{type_kind!s} -> {ty}"):
2057
+ irmod = ir.Module(context=ctx)
2058
+ ir.GlobalVariable(irmod, ty, name='gv')
2059
+ asm = str(irmod)
2060
+ mod = llvm.parse_assembly(asm)
2061
+ gv = mod.get_global_variable("gv")
2062
+ gvty = gv.global_value_type
2063
+ got = gvty.as_ir(ir.Context()) # fresh context
2064
+ self.assertEqual(got, ty)
2065
+ self.assertIsInstance(got, irtype)
2066
+
2067
+ def _check_typeref_as_ir_for_wrappers(self, asm, target_symbol):
2068
+ # Get a clang++ defined function from a llvm ir
2069
+ mod = llvm.parse_assembly(asm)
2070
+ cppfn = mod.get_function(target_symbol)
2071
+ cppfntype = cppfn.global_value_type
2072
+
2073
+ # Get the function type into a new context
2074
+ my_context = ir.Context() # don't populate global context
2075
+ ty = cppfntype.as_ir(ir_ctx=my_context)
2076
+
2077
+ # Build a wrapper module for the cpp function
2078
+ wrapper_mod = ir.Module(context=my_context)
2079
+ # declare the original function
2080
+ declfn = ir.Function(wrapper_mod, ty, name=cppfn.name)
2081
+ # populate the wrapper function
2082
+ wrapfn = ir.Function(wrapper_mod, ty, name="wrapper")
2083
+ builder = ir.IRBuilder(wrapfn.append_basic_block())
2084
+ # just call the original function
2085
+ builder.call(declfn, wrapfn.args)
2086
+ builder.ret_void()
2087
+ # Create a new LLVM module with the wrapper
2088
+ new_mod = llvm.parse_assembly(str(wrapper_mod))
2089
+ self.assertTrue(new_mod.get_function(declfn.name).is_declaration,
2090
+ msg="declfn must not have a body")
2091
+ # Merge/link the original module into the new module
2092
+ new_mod.link_in(mod, preserve=True)
2093
+ self.assertEqual(len(list(new_mod.functions)),
2094
+ len(list(mod.functions)) + 1,
2095
+ msg="the only new function is the wrapper")
2096
+ self.assertFalse(new_mod.get_function(declfn.name).is_declaration,
2097
+ msg="declfn must have a body now")
2098
+ self.assertEqual(new_mod.get_function(declfn.name).global_value_type,
2099
+ new_mod.get_function(wrapfn.name).global_value_type,
2100
+ msg="declfn and wrapfn must have the same llvm Type")
2101
+
2102
+ def test_typeref_as_ir_for_wrappers_of_cpp_class(self):
2103
+ """Exercise extracting C++ defined class types.
2104
+ Contains both opaque and non-opaque class definitions.
2105
+ """
2106
+ self._check_typeref_as_ir_for_wrappers(
2107
+ asm_cpp_class,
2108
+ "_Z3fooP7MyClass14MyClassDefined",
2109
+ )
2110
+
2111
+ def test_typeref_as_ir_for_wrappers_of_cpp_vector_struct(self):
2112
+ """Exercise extracting C++ struct types that are passed as vectors.
2113
+
2114
+ IA64 ABI on x86_64 will put struct with two floats as
2115
+ a vector of two floats.
2116
+ """
2117
+ self._check_typeref_as_ir_for_wrappers(
2118
+ asm_cpp_vector,
2119
+ "_Z3foo8Vector2DPS_",
2120
+ )
1822
2121
 
1823
2122
 
1824
2123
  class TestTarget(BaseTest):
@@ -1860,6 +2159,57 @@ class TestTarget(BaseTest):
1860
2159
  self.assertIn(target.name, s)
1861
2160
  self.assertIn(target.description, s)
1862
2161
 
2162
+ def test_get_parts_from_triple(self):
2163
+ # Tests adapted from llvm-14::llvm/unittests/ADT/TripleTest.cpp
2164
+ cases = [
2165
+ ("x86_64-scei-ps4",
2166
+ llvm.targets.Triple(Arch="x86_64", SubArch='',
2167
+ Vendor="scei", OS="ps4",
2168
+ Env="unknown", ObjectFormat="ELF")),
2169
+ ("x86_64-sie-ps4",
2170
+ llvm.targets.Triple(Arch="x86_64", SubArch='',
2171
+ Vendor="scei", OS="ps4",
2172
+ Env="unknown", ObjectFormat="ELF")),
2173
+ ("powerpc-dunno-notsure",
2174
+ llvm.targets.Triple(Arch="powerpc", SubArch='',
2175
+ Vendor="unknown", OS="unknown",
2176
+ Env="unknown", ObjectFormat="ELF")),
2177
+ ("powerpcspe-unknown-freebsd",
2178
+ llvm.targets.Triple(Arch="powerpc", SubArch='spe',
2179
+ Vendor="unknown", OS="freebsd",
2180
+ Env="unknown", ObjectFormat="ELF")),
2181
+ ("armv6hl-none-linux-gnueabi",
2182
+ llvm.targets.Triple(Arch="arm", SubArch='v6hl',
2183
+ Vendor="unknown", OS="linux",
2184
+ Env="gnueabi", ObjectFormat="ELF")),
2185
+ ("i686-unknown-linux-gnu",
2186
+ llvm.targets.Triple(Arch="i386", SubArch='',
2187
+ Vendor="unknown", OS="linux",
2188
+ Env="gnu", ObjectFormat="ELF")),
2189
+ ("i686-apple-macosx",
2190
+ llvm.targets.Triple(Arch="i386", SubArch='',
2191
+ Vendor="apple", OS="macosx",
2192
+ Env="unknown", ObjectFormat="MachO")),
2193
+ ("i686-dunno-win32",
2194
+ llvm.targets.Triple(Arch="i386", SubArch='',
2195
+ Vendor="unknown", OS="windows",
2196
+ Env="msvc", ObjectFormat="COFF")),
2197
+ ("s390x-ibm-zos",
2198
+ llvm.targets.Triple(Arch="s390x", SubArch='',
2199
+ Vendor="ibm", OS="zos",
2200
+ Env="unknown", ObjectFormat="GOFF")),
2201
+ ("wasm64-wasi",
2202
+ llvm.targets.Triple(Arch="wasm64", SubArch='',
2203
+ Vendor="unknown", OS="wasi",
2204
+ Env="unknown", ObjectFormat="Wasm")),
2205
+ ]
2206
+
2207
+ for case in cases:
2208
+ triple_str, triple_obj = case
2209
+ res = llvm.get_triple_parts(triple_str)
2210
+
2211
+ self.assertEqual(res, triple_obj)
2212
+
1863
2213
 
1864
2214
  class TestTargetData(BaseTest):
1865
2215
 
@@ -1875,10 +2225,10 @@ class TestTargetData(BaseTest):
1875
2225
  td = self.target_data()
1876
2226
 
1877
2227
  glob = self.glob()
1878
- self.assertEqual(td.get_pointee_abi_size(glob.type), 4)
2228
+ self.assertEqual(td.get_abi_size(glob.global_value_type), 4)
1879
2229
 
1880
2230
  glob = self.glob("glob_struct")
1881
- self.assertEqual(td.get_pointee_abi_size(glob.type), 24)
2231
+ self.assertEqual(td.get_abi_size(glob.global_value_type), 24)
1882
2232
 
1883
2233
  def test_get_struct_element_offset(self):
1884
2234
  td = self.target_data()
@@ -1887,7 +2237,7 @@ class TestTargetData(BaseTest):
1887
2237
  with self.assertRaises(ValueError):
1888
2238
  td.get_element_offset(glob.type, 0)
1889
2239
 
1890
- struct_type = glob.type.element_type
2240
+ struct_type = glob.global_value_type
1891
2241
  self.assertEqual(td.get_element_offset(struct_type, 0), 0)
1892
2242
  self.assertEqual(td.get_element_offset(struct_type, 1), 8)
1893
2243
 
@@ -2153,6 +2503,8 @@ class TestPasses(BaseTest, PassManagerTestMixin):
2153
2503
  return llvm.create_module_pass_manager()
2154
2504
 
2155
2505
  def test_populate(self):
2506
+ llvm_ver = llvm.llvm_version_info[0]
2507
+
2156
2508
  pm = self.pm()
2157
2509
  pm.add_target_library_info("") # unspecified target triple
2158
2510
  pm.add_constant_merge_pass()
@@ -2177,12 +2529,13 @@ class TestPasses(BaseTest, PassManagerTestMixin):
2177
2529
  pm.add_aggressive_dead_code_elimination_pass()
2178
2530
  pm.add_aa_eval_pass()
2179
2531
  pm.add_always_inliner_pass()
2180
- if llvm_version_major < 15:
2181
- pm.add_arg_promotion_pass(42)
2182
2532
  pm.add_break_critical_edges_pass()
2183
2533
  pm.add_dead_store_elimination_pass()
2184
2534
  pm.add_reverse_post_order_function_attrs_pass()
2185
- pm.add_aggressive_instruction_combining_pass()
2535
+
2536
+ if llvm_ver < 16:
2537
+ pm.add_aggressive_instruction_combining_pass()
2538
+
2186
2539
  pm.add_internalize_pass()
2187
2540
  pm.add_jump_threading_pass(7)
2188
2541
  pm.add_lcssa_pass()
@@ -2193,8 +2546,6 @@ class TestPasses(BaseTest, PassManagerTestMixin):
2193
2546
  pm.add_loop_simplification_pass()
2194
2547
  pm.add_loop_unroll_pass()
2195
2548
  pm.add_loop_unroll_and_jam_pass()
2196
- if llvm_version_major < 15:
2197
- pm.add_loop_unswitch_pass()
2198
2549
  pm.add_lower_atomic_pass()
2199
2550
  pm.add_lower_invoke_pass()
2200
2551
  pm.add_lower_switch_pass()
@@ -2202,7 +2553,10 @@ class TestPasses(BaseTest, PassManagerTestMixin):
2202
2553
  pm.add_merge_functions_pass()
2203
2554
  pm.add_merge_returns_pass()
2204
2555
  pm.add_partial_inlining_pass()
2205
- pm.add_prune_exception_handling_pass()
2556
+
2557
+ if llvm_ver < 16:
2558
+ pm.add_prune_exception_handling_pass()
2559
+
2206
2560
  pm.add_reassociate_expressions_pass()
2207
2561
  pm.add_demote_register_to_memory_pass()
2208
2562
  pm.add_sink_pass()
@@ -2347,6 +2701,14 @@ class TestTypeParsing(BaseTest):
2347
2701
  # Also test constant text repr
2348
2702
  gv.initializer = ir.Constant(typ, [1])
2349
2703
 
2704
+ # Packed layout created from Constant.literal_struct
2705
+ with self.check_parsing() as mod:
2706
+ const = ir.Constant.literal_struct([ir.IntType(32)(1),
2707
+ ir.IntType(32)(2)],
2708
+ packed=True)
2709
+ gv = ir.GlobalVariable(mod, const.type, "foo")
2710
+ gv.initializer = const
2711
+
2350
2712
 
2351
2713
  class TestGlobalConstructors(TestMCJit):
2352
2714
  def test_global_ctors_dtors(self):
@@ -2581,5 +2943,266 @@ class TestLLVMLockCallbacks(BaseTest):
2581
2943
  llvm.ffi.unregister_lock_callback(acq, rel)
2582
2944
 
2583
2945
 
2946
+ class TestPipelineTuningOptions(BaseTest):
2947
+
2948
+ def pto(self):
2949
+ return llvm.create_pipeline_tuning_options()
2950
+
2951
+ def test_close(self):
2952
+ pto = self.pto()
2953
+ pto.close()
2954
+
2955
+ def test_speed_level(self):
2956
+ pto = self.pto()
2957
+ self.assertIsInstance(pto.speed_level, int)
2958
+ for i in range(4):
2959
+ pto.speed_level = i
2960
+ self.assertEqual(pto.speed_level, i)
2961
+
2962
+ def test_size_level(self):
2963
+ pto = self.pto()
2964
+ self.assertIsInstance(pto.size_level, int)
2965
+ for i in range(3):
2966
+ pto.size_level = i
2967
+ self.assertEqual(pto.size_level, i)
2968
+
2969
+ # // FIXME: Available from llvm16
2970
+ # def test_inlining_threshold(self):
2971
+ # pto = self.pto()
2972
+ # with self.assertRaises(NotImplementedError):
2973
+ # pto.inlining_threshold
2974
+ # for i in (25, 80, 350):
2975
+ # pto.inlining_threshold = i
2976
+
2977
+ def test_loop_interleaving(self):
2978
+ pto = self.pto()
2979
+ self.assertIsInstance(pto.loop_interleaving, bool)
2980
+ for b in (True, False):
2981
+ pto.loop_interleaving = b
2982
+ self.assertEqual(pto.loop_interleaving, b)
2983
+
2984
+ def test_loop_vectorization(self):
2985
+ pto = self.pto()
2986
+ self.assertIsInstance(pto.loop_vectorization, bool)
2987
+ for b in (True, False):
2988
+ pto.loop_vectorization = b
2989
+ self.assertEqual(pto.loop_vectorization, b)
2990
+
2991
+ def test_slp_vectorization(self):
2992
+ pto = self.pto()
2993
+ self.assertIsInstance(pto.slp_vectorization, bool)
2994
+ for b in (True, False):
2995
+ pto.slp_vectorization = b
2996
+ self.assertEqual(pto.slp_vectorization, b)
2997
+
2998
+ def test_loop_unrolling(self):
2999
+ pto = self.pto()
3000
+ self.assertIsInstance(pto.loop_unrolling, bool)
3001
+ for b in (True, False):
3002
+ pto.loop_unrolling = b
3003
+ self.assertEqual(pto.loop_unrolling, b)
3004
+
3005
+ def test_speed_level_constraints(self):
3006
+ pto = self.pto()
3007
+ with self.assertRaises(ValueError):
3008
+ pto.speed_level = 4
3009
+ with self.assertRaises(ValueError):
3010
+ pto.speed_level = -1
3011
+
3012
+ def test_size_level_constraints(self):
3013
+ pto = self.pto()
3014
+ with self.assertRaises(ValueError):
3015
+ pto.size_level = 3
3016
+ with self.assertRaises(ValueError):
3017
+ pto.speed_level = -1
3018
+ with self.assertRaises(ValueError):
3019
+ pto.speed_level = 3
3020
+ pto.size_level = 2
3021
+
3022
+
3023
+ class NewPassManagerMixin(object):
3024
+
3025
+ def pb(self, speed_level=0, size_level=0):
3026
+ tm = self.target_machine(jit=False)
3027
+ pto = llvm.create_pipeline_tuning_options(speed_level, size_level)
3028
+ pb = llvm.create_pass_builder(tm, pto)
3029
+ return pb
3030
+
3031
+
3032
+ class TestPassBuilder(BaseTest, NewPassManagerMixin):
3033
+
3034
+ def test_close(self):
3035
+ pb = self.pb()
3036
+ pb.close()
3037
+
3038
+ def test_pto(self):
3039
+ tm = self.target_machine(jit=False)
3040
+ pto = llvm.create_pipeline_tuning_options(3, 0)
3041
+ pto.inlining_threshold = 2
3042
+ pto.loop_interleaving = True
3043
+ pto.loop_vectorization = True
3044
+ pto.slp_vectorization = True
3045
+ pto.loop_unrolling = False
3046
+ pb = llvm.create_pass_builder(tm, pto)
3047
+ pb.close()
3048
+
3049
+ def test_get_module_pass_manager(self):
3050
+ pb = self.pb()
3051
+ mpm = pb.getModulePassManager()
3052
+ mpm.run(self.module(), pb)
3053
+ pb.close()
3054
+
3055
+ def test_get_function_pass_manager(self):
3056
+ pb = self.pb()
3057
+ fpm = pb.getFunctionPassManager()
3058
+ fpm.run(self.module().get_function("sum"), pb)
3059
+ pb.close()
3060
+
3061
+
3062
+ class TestNewModulePassManager(BaseTest, NewPassManagerMixin):
3063
+ def pm(self):
3064
+ return llvm.create_new_module_pass_manager()
3065
+
3066
+ def run_o_n(self, level):
3067
+ mod = self.module()
3068
+ orig_asm = str(mod)
3069
+ pb = self.pb(speed_level=level, size_level=0)
3070
+ mpm = pb.getModulePassManager()
3071
+ mpm.run(mod, pb)
3072
+ optimized_asm = str(mod)
3073
+ return orig_asm, optimized_asm
3074
+
3075
+ def test_close(self):
3076
+ mpm = self.pm()
3077
+ mpm.close()
3078
+
3079
+ def test_run_o3(self):
3080
+ orig_asm, optimized_asm = self.run_o_n(3)
3081
+ self.assertIn("%.4", orig_asm)
3082
+ self.assertNotIn("%.4", optimized_asm)
3083
+
3084
+ def test_run_o0(self):
3085
+ orig_asm, optimized_asm = self.run_o_n(0)
3086
+ self.assertIn("%.4", orig_asm)
3087
+ self.assertIn("%.4", optimized_asm)
3088
+
3089
+ def test_instcombine(self):
3090
+ pb = self.pb()
3091
+ mpm = self.pm()
3092
+ mpm.add_instruction_combine_pass()
3093
+ mod = self.module(asm_sum4)
3094
+ orig_asm = str(mod)
3095
+ mpm.run(mod, pb)
3096
+ optimized_asm = str(mod)
3097
+ self.assertIn("%.3", orig_asm)
3098
+ self.assertNotIn("%.3", optimized_asm)
3099
+
3100
+ def test_optnone(self):
3101
+ pb = self.pb(speed_level=3, size_level=0)
3102
+ orig_asm = str(asm_alloca_optnone.replace("optnone ", ""))
3103
+ mod = llvm.parse_assembly(orig_asm)
3104
+ mpm = pb.getModulePassManager()
3105
+ mpm.run(mod, pb)
3106
+ optimized_asm = str(mod)
3107
+ self.assertIn("alloca", orig_asm)
3108
+ self.assertNotIn("alloca", optimized_asm)
3109
+
3110
+ # Module shouldn't be optimized if the function has `optnone` attached
3111
+ orig_asm_optnone = str(asm_alloca_optnone)
3112
+ mpm = pb.getModulePassManager()
3113
+ mod = llvm.parse_assembly(orig_asm_optnone)
3114
+ mpm.run(mod, pb)
3115
+ optimized_asm_optnone = str(mod)
3116
+ self.assertIn("alloca", orig_asm_optnone)
3117
+ self.assertIn("alloca", optimized_asm_optnone)
3118
+
3119
+ def test_add_passes(self):
3120
+ mpm = self.pm()
3121
+ mpm.add_verifier()
3122
+ mpm.add_aa_eval_pass()
3123
+ mpm.add_simplify_cfg_pass()
3124
+ mpm.add_loop_unroll_pass()
3125
+ mpm.add_loop_rotate_pass()
3126
+ mpm.add_instruction_combine_pass()
3127
+ mpm.add_jump_threading_pass()
3128
+ mpm.add_refprune_pass()
3129
+
3130
+
3131
+ class TestNewFunctionPassManager(BaseTest, NewPassManagerMixin):
3132
+ def pm(self):
3133
+ return llvm.create_new_function_pass_manager()
3134
+
3135
+ def test_close(self):
3136
+ fpm = self.pm()
3137
+ fpm.close()
3138
+
3139
+ def run_o_n(self, level):
3140
+ mod = self.module()
3141
+ fun = mod.get_function("sum")
3142
+ orig_asm = str(fun)
3143
+ pb = self.pb(speed_level=level, size_level=0)
3144
+ fpm = pb.getFunctionPassManager()
3145
+ fpm.run(fun, pb)
3146
+ optimized_asm = str(fun)
3147
+ return orig_asm, optimized_asm
3148
+
3149
+ def test_run_o3(self):
3150
+ orig_asm, optimized_asm = self.run_o_n(3)
3151
+ self.assertIn("%.4", orig_asm)
3152
+ self.assertNotIn("%.4", optimized_asm)
3153
+
3154
+ def test_run_o0(self):
3155
+ orig_asm, optimized_asm = self.run_o_n(0)
3156
+ self.assertIn("%.4", orig_asm)
3157
+ self.assertIn("%.4", optimized_asm)
3158
+
3159
+ def test_optnone(self):
3160
+ pb = self.pb(speed_level=3, size_level=0)
3161
+ orig_asm = str(asm_alloca_optnone.replace("optnone ", ""))
3162
+ fun = llvm.parse_assembly(orig_asm).get_function("foo")
3163
+ fpm = pb.getFunctionPassManager()
3164
+ fpm.run(fun, pb)
3165
+ optimized_asm = str(fun)
3166
+ self.assertIn("alloca", orig_asm)
3167
+ self.assertNotIn("alloca", optimized_asm)
3168
+
3169
+ # Function shouldn't be optimized if the function has `optnone` attached
3170
+ orig_asm_optnone = str(asm_alloca_optnone)
3171
+ fun = llvm.parse_assembly(orig_asm_optnone).get_function("foo")
3172
+ fpm = pb.getFunctionPassManager()
3173
+ fpm.run(fun, pb)
3174
+ optimized_asm_optnone = str(fun)
3175
+ self.assertIn("alloca", orig_asm_optnone)
3176
+ self.assertIn("alloca", optimized_asm_optnone)
3177
+
3178
+ def test_instcombine(self):
3179
+ pb = self.pb()
3180
+ fpm = self.pm()
3181
+ fun = self.module(asm_sum4).get_function("sum")
3182
+ fpm.add_instruction_combine_pass()
3183
+ orig_asm = str(fun)
3184
+ fpm.run(fun, pb)
3185
+ optimized_asm = str(fun)
3186
+ self.assertIn("%.3", orig_asm)
3187
+ self.assertNotIn("%.3", optimized_asm)
3188
+
3189
+ # This should not crash
3190
+ def test_declarations(self):
3191
+ pb = self.pb(3)
3192
+ fpm = pb.getFunctionPassManager()
3193
+ for fun in llvm.parse_assembly(asm_declaration).functions:
3194
+ fpm.run(fun, pb)
3195
+
3196
+ def test_add_passes(self):
3197
+ fpm = self.pm()
3198
+ fpm.add_aa_eval_pass()
3199
+ fpm.add_simplify_cfg_pass()
3200
+ fpm.add_loop_unroll_pass()
3201
+ fpm.add_loop_rotate_pass()
3202
+ fpm.add_instruction_combine_pass()
3203
+ fpm.add_jump_threading_pass()
3204
+ fpm.add_refprune_pass()
3205
+
3206
+
2584
3207
  if __name__ == "__main__":
2585
3208
  unittest.main()