@@ -67,7 +67,7 @@ impl<'a, 'll> SBuilder<'a, 'll> {
67
67
) -> & ' ll Value {
68
68
debug ! ( "call {:?} with args ({:?})" , llfn, args) ;
69
69
70
- let args = self . check_call ( "call" , llty, llfn, args) ;
70
+ let args = self . cast_arguments ( "call" , llty, llfn, args) ;
71
71
let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
72
72
let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
73
73
if let Some ( funclet_bundle) = funclet_bundle {
@@ -101,6 +101,51 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
101
101
unsafe { llvm:: LLVMBuildBitCast ( self . llbuilder , val, dest_ty, UNNAMED ) }
102
102
}
103
103
104
+ pub ( crate ) fn cast_vector_to_tile ( & mut self , val : & ' ll Value ) -> & ' ll Value {
105
+ let vector_type = self . cx . val_ty ( val) ;
106
+
107
+ assert ! ( self . cx. type_kind( vector_type) == TypeKind :: Vector ) ;
108
+
109
+ let intrinsic = llvm:: Intrinsic :: lookup ( b"llvm.x86.cast.vector.to.tile" . as_ref ( ) ) . unwrap ( ) ;
110
+ let ( fn_ty, f) = self . cx . get_or_declare_intrinsic ( intrinsic, & [ vector_type] ) ;
111
+ unsafe {
112
+ llvm:: LLVMBuildCallWithOperandBundles (
113
+ self . llbuilder ,
114
+ fn_ty,
115
+ f,
116
+ [ val] . as_ptr ( ) . cast ( ) ,
117
+ 1 ,
118
+ [ ] . as_ptr ( ) ,
119
+ 0 ,
120
+ c"" . as_ptr ( ) ,
121
+ )
122
+ }
123
+ }
124
+
125
+ pub ( crate ) fn cast_tile_to_vector (
126
+ & mut self ,
127
+ val : & ' ll Value ,
128
+ vector_type : & ' ll Type ,
129
+ ) -> & ' ll Value {
130
+ assert ! ( self . cx. val_ty( val) == self . cx. type_x86amx( ) ) ;
131
+ assert ! ( self . cx. type_kind( vector_type) == TypeKind :: Vector ) ;
132
+
133
+ let intrinsic = llvm:: Intrinsic :: lookup ( b"llvm.x86.cast.tile.to.vector" ) . unwrap ( ) ;
134
+ let ( fn_ty, f) = self . cx . get_or_declare_intrinsic ( intrinsic, & [ vector_type] ) ;
135
+ unsafe {
136
+ llvm:: LLVMBuildCallWithOperandBundles (
137
+ self . llbuilder ,
138
+ fn_ty,
139
+ f,
140
+ [ val] . as_ptr ( ) . cast ( ) ,
141
+ 1 ,
142
+ [ ] . as_ptr ( ) ,
143
+ 0 ,
144
+ c"" . as_ptr ( ) ,
145
+ )
146
+ }
147
+ }
148
+
104
149
pub ( crate ) fn ret_void ( & mut self ) {
105
150
llvm:: LLVMBuildRetVoid ( self . llbuilder ) ;
106
151
}
@@ -349,7 +394,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
349
394
) -> & ' ll Value {
350
395
debug ! ( "invoke {:?} with args ({:?})" , llfn, args) ;
351
396
352
- let args = self . check_call ( "invoke" , llty, llfn, args) ;
397
+ let args = self . cast_arguments ( "invoke" , llty, llfn, args) ;
353
398
let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
354
399
let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
355
400
if let Some ( funclet_bundle) = funclet_bundle {
@@ -381,8 +426,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
381
426
} ;
382
427
if let Some ( fn_abi) = fn_abi {
383
428
fn_abi. apply_attrs_callsite ( self , invoke) ;
429
+ self . cast_return ( fn_abi, llfn, invoke)
430
+ } else {
431
+ invoke
384
432
}
385
- invoke
386
433
}
387
434
388
435
fn unreachable ( & mut self ) {
@@ -1404,7 +1451,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1404
1451
) -> & ' ll Value {
1405
1452
debug ! ( "call {:?} with args ({:?})" , llfn, args) ;
1406
1453
1407
- let args = self . check_call ( "call" , llty, llfn, args) ;
1454
+ let args = self . cast_arguments ( "call" , llty, llfn, args) ;
1408
1455
let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
1409
1456
let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
1410
1457
if let Some ( funclet_bundle) = funclet_bundle {
@@ -1434,8 +1481,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1434
1481
} ;
1435
1482
if let Some ( fn_abi) = fn_abi {
1436
1483
fn_abi. apply_attrs_callsite ( self , call) ;
1484
+ self . cast_return ( fn_abi, llfn, call)
1485
+ } else {
1486
+ call
1437
1487
}
1438
- call
1439
1488
}
1440
1489
1441
1490
fn zext ( & mut self , val : & ' ll Value , dest_ty : & ' ll Type ) -> & ' ll Value {
@@ -1596,7 +1645,7 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1596
1645
ret. expect ( "LLVM does not have support for catchret" )
1597
1646
}
1598
1647
1599
- fn check_call < ' b > (
1648
+ fn cast_arguments < ' b > (
1600
1649
& mut self ,
1601
1650
typ : & str ,
1602
1651
fn_ty : & ' ll Type ,
@@ -1627,7 +1676,11 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1627
1676
Expected {:?} for param {}, got {:?}; injecting bitcast",
1628
1677
llfn, expected_ty, i, actual_ty
1629
1678
) ;
1630
- self . bitcast ( actual_val, expected_ty)
1679
+ if self . cx . type_kind ( expected_ty) == TypeKind :: X86_AMX {
1680
+ self . cast_vector_to_tile ( actual_val)
1681
+ } else {
1682
+ self . bitcast ( actual_val, expected_ty)
1683
+ }
1631
1684
} else {
1632
1685
actual_val
1633
1686
}
@@ -1708,6 +1761,31 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1708
1761
self . call ( self . type_func ( & [ src_ty] , dest_ty) , None , None , f, & [ val] , None , None )
1709
1762
}
1710
1763
1764
+ fn cast_return (
1765
+ & mut self ,
1766
+ fn_abi : & FnAbi < ' tcx , Ty < ' tcx > > ,
1767
+ llfn : & ' ll Value ,
1768
+ ret : & ' ll Value ,
1769
+ ) -> & ' ll Value {
1770
+ let expected_ty = fn_abi. llvm_return_type ( self . cx ) ;
1771
+ let actual_ty = self . cx . val_ty ( ret) ;
1772
+
1773
+ if expected_ty != actual_ty {
1774
+ debug ! (
1775
+ "type mismatch in function call of {:?}. \
1776
+ Expected {:?} for return value, got {:?}; injecting bitcast",
1777
+ llfn, expected_ty, actual_ty
1778
+ ) ;
1779
+ if self . cx . type_kind ( actual_ty) == TypeKind :: X86_AMX {
1780
+ self . cast_tile_to_vector ( ret, expected_ty)
1781
+ } else {
1782
+ self . bitcast ( ret, expected_ty)
1783
+ }
1784
+ } else {
1785
+ ret
1786
+ }
1787
+ }
1788
+
1711
1789
pub ( crate ) fn landing_pad (
1712
1790
& mut self ,
1713
1791
ty : & ' ll Type ,
@@ -1737,7 +1815,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1737
1815
) -> & ' ll Value {
1738
1816
debug ! ( "invoke {:?} with args ({:?})" , llfn, args) ;
1739
1817
1740
- let args = self . check_call ( "callbr" , llty, llfn, args) ;
1818
+ let args = self . cast_arguments ( "callbr" , llty, llfn, args) ;
1741
1819
let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
1742
1820
let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
1743
1821
if let Some ( funclet_bundle) = funclet_bundle {
@@ -1770,8 +1848,10 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1770
1848
} ;
1771
1849
if let Some ( fn_abi) = fn_abi {
1772
1850
fn_abi. apply_attrs_callsite ( self , callbr) ;
1851
+ self . cast_return ( fn_abi, llfn, callbr)
1852
+ } else {
1853
+ callbr
1773
1854
}
1774
- callbr
1775
1855
}
1776
1856
1777
1857
// Emits CFI pointer type membership tests.
0 commit comments