@@ -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,24 @@ 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
+ self . call_intrinsic ( "llvm.x86.cast.vector.to.tile" , & [ vector_type] , & [ val] )
109
+ }
110
+
111
+ pub ( crate ) fn cast_tile_to_vector (
112
+ & mut self ,
113
+ val : & ' ll Value ,
114
+ vector_type : & ' ll Type ,
115
+ ) -> & ' ll Value {
116
+ assert ! ( self . cx. val_ty( val) == self . cx. type_x86amx( ) ) ;
117
+ assert ! ( self . cx. type_kind( vector_type) == TypeKind :: Vector ) ;
118
+
119
+ self . call_intrinsic ( "llvm.x86.cast.tile.to.vector" , & [ vector_type] , & [ val] )
120
+ }
121
+
104
122
pub ( crate ) fn ret_void ( & mut self ) {
105
123
llvm:: LLVMBuildRetVoid ( self . llbuilder ) ;
106
124
}
@@ -349,7 +367,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
349
367
) -> & ' ll Value {
350
368
debug ! ( "invoke {:?} with args ({:?})" , llfn, args) ;
351
369
352
- let args = self . check_call ( "invoke" , llty, llfn, args) ;
370
+ let args = self . cast_arguments ( "invoke" , llty, llfn, args) ;
353
371
let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
354
372
let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
355
373
if let Some ( funclet_bundle) = funclet_bundle {
@@ -381,8 +399,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
381
399
} ;
382
400
if let Some ( fn_abi) = fn_abi {
383
401
fn_abi. apply_attrs_callsite ( self , invoke) ;
402
+ self . cast_return ( fn_abi, llfn, invoke)
403
+ } else {
404
+ invoke
384
405
}
385
- invoke
386
406
}
387
407
388
408
fn unreachable ( & mut self ) {
@@ -1348,7 +1368,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1348
1368
) -> & ' ll Value {
1349
1369
debug ! ( "call {:?} with args ({:?})" , llfn, args) ;
1350
1370
1351
- let args = self . check_call ( "call" , llty, llfn, args) ;
1371
+ let args = self . cast_arguments ( "call" , llty, llfn, args) ;
1352
1372
let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
1353
1373
let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
1354
1374
if let Some ( funclet_bundle) = funclet_bundle {
@@ -1378,8 +1398,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
1378
1398
} ;
1379
1399
if let Some ( fn_abi) = fn_abi {
1380
1400
fn_abi. apply_attrs_callsite ( self , call) ;
1401
+ self . cast_return ( fn_abi, llfn, call)
1402
+ } else {
1403
+ call
1381
1404
}
1382
- call
1383
1405
}
1384
1406
1385
1407
fn zext ( & mut self , val : & ' ll Value , dest_ty : & ' ll Type ) -> & ' ll Value {
@@ -1540,7 +1562,7 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1540
1562
ret. expect ( "LLVM does not have support for catchret" )
1541
1563
}
1542
1564
1543
- fn check_call < ' b > (
1565
+ fn cast_arguments < ' b > (
1544
1566
& mut self ,
1545
1567
typ : & str ,
1546
1568
fn_ty : & ' ll Type ,
@@ -1571,7 +1593,11 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1571
1593
Expected {:?} for param {}, got {:?}; injecting bitcast",
1572
1594
llfn, expected_ty, i, actual_ty
1573
1595
) ;
1574
- self . bitcast ( actual_val, expected_ty)
1596
+ if self . cx . type_kind ( expected_ty) == TypeKind :: X86_AMX {
1597
+ self . cast_vector_to_tile ( actual_val)
1598
+ } else {
1599
+ self . bitcast ( actual_val, expected_ty)
1600
+ }
1575
1601
} else {
1576
1602
actual_val
1577
1603
}
@@ -1591,7 +1617,7 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
1591
1617
llfn : & ' ll Value ,
1592
1618
args : & [ & ' ll Value ] ,
1593
1619
) -> & ' ll Value {
1594
- let args = self . check_call ( "simple call" , fn_ty, llfn, args) ;
1620
+ let args = self . cast_arguments ( "simple call" , fn_ty, llfn, args) ;
1595
1621
1596
1622
unsafe {
1597
1623
llvm:: LLVMBuildCall2 (
@@ -1692,6 +1718,31 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1692
1718
self . simple_call ( fn_ty, llfn, & [ ptr1, ptr2, num] )
1693
1719
}
1694
1720
1721
+ fn cast_return (
1722
+ & mut self ,
1723
+ fn_abi : & FnAbi < ' tcx , Ty < ' tcx > > ,
1724
+ llfn : & ' ll Value ,
1725
+ ret : & ' ll Value ,
1726
+ ) -> & ' ll Value {
1727
+ let expected_ty = fn_abi. llvm_return_type ( self . cx ) ;
1728
+ let actual_ty = self . cx . val_ty ( ret) ;
1729
+
1730
+ if expected_ty != actual_ty {
1731
+ debug ! (
1732
+ "type mismatch in function call of {:?}. \
1733
+ Expected {:?} for return value, got {:?}; injecting bitcast",
1734
+ llfn, expected_ty, actual_ty
1735
+ ) ;
1736
+ if self . cx . type_kind ( actual_ty) == TypeKind :: X86_AMX {
1737
+ self . cast_tile_to_vector ( ret, expected_ty)
1738
+ } else {
1739
+ self . bitcast ( ret, expected_ty)
1740
+ }
1741
+ } else {
1742
+ ret
1743
+ }
1744
+ }
1745
+
1695
1746
pub ( crate ) fn landing_pad (
1696
1747
& mut self ,
1697
1748
ty : & ' ll Type ,
@@ -1721,7 +1772,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1721
1772
) -> & ' ll Value {
1722
1773
debug ! ( "invoke {:?} with args ({:?})" , llfn, args) ;
1723
1774
1724
- let args = self . check_call ( "callbr" , llty, llfn, args) ;
1775
+ let args = self . cast_arguments ( "callbr" , llty, llfn, args) ;
1725
1776
let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
1726
1777
let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
1727
1778
if let Some ( funclet_bundle) = funclet_bundle {
@@ -1754,8 +1805,10 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1754
1805
} ;
1755
1806
if let Some ( fn_abi) = fn_abi {
1756
1807
fn_abi. apply_attrs_callsite ( self , callbr) ;
1808
+ self . cast_return ( fn_abi, llfn, callbr)
1809
+ } else {
1810
+ callbr
1757
1811
}
1758
- callbr
1759
1812
}
1760
1813
1761
1814
// Emits CFI pointer type membership tests.
0 commit comments