@@ -67,7 +67,7 @@ impl<'a, 'll> SBuilder<'a, 'll> {
6767 ) -> & ' ll Value {
6868 debug ! ( "call {:?} with args ({:?})" , llfn, args) ;
6969
70- let args = self . check_call ( "call" , llty, llfn, args) ;
70+ let args = self . cast_arguments ( "call" , llty, llfn, args) ;
7171 let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
7272 let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
7373 if let Some ( funclet_bundle) = funclet_bundle {
@@ -101,6 +101,24 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
101101 unsafe { llvm:: LLVMBuildBitCast ( self . llbuilder , val, dest_ty, UNNAMED ) }
102102 }
103103
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+
104122 pub ( crate ) fn ret_void ( & mut self ) {
105123 llvm:: LLVMBuildRetVoid ( self . llbuilder ) ;
106124 }
@@ -349,7 +367,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
349367 ) -> & ' ll Value {
350368 debug ! ( "invoke {:?} with args ({:?})" , llfn, args) ;
351369
352- let args = self . check_call ( "invoke" , llty, llfn, args) ;
370+ let args = self . cast_arguments ( "invoke" , llty, llfn, args) ;
353371 let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
354372 let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
355373 if let Some ( funclet_bundle) = funclet_bundle {
@@ -381,8 +399,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
381399 } ;
382400 if let Some ( fn_abi) = fn_abi {
383401 fn_abi. apply_attrs_callsite ( self , invoke) ;
402+ self . cast_return ( fn_abi, llfn, invoke)
403+ } else {
404+ invoke
384405 }
385- invoke
386406 }
387407
388408 fn unreachable ( & mut self ) {
@@ -1348,7 +1368,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13481368 ) -> & ' ll Value {
13491369 debug ! ( "call {:?} with args ({:?})" , llfn, args) ;
13501370
1351- let args = self . check_call ( "call" , llty, llfn, args) ;
1371+ let args = self . cast_arguments ( "call" , llty, llfn, args) ;
13521372 let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
13531373 let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
13541374 if let Some ( funclet_bundle) = funclet_bundle {
@@ -1378,8 +1398,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13781398 } ;
13791399 if let Some ( fn_abi) = fn_abi {
13801400 fn_abi. apply_attrs_callsite ( self , call) ;
1401+ self . cast_return ( fn_abi, llfn, call)
1402+ } else {
1403+ call
13811404 }
1382- call
13831405 }
13841406
13851407 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> {
15401562 ret. expect ( "LLVM does not have support for catchret" )
15411563 }
15421564
1543- fn check_call < ' b > (
1565+ fn cast_arguments < ' b > (
15441566 & mut self ,
15451567 typ : & str ,
15461568 fn_ty : & ' ll Type ,
@@ -1571,7 +1593,11 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
15711593 Expected {:?} for param {}, got {:?}; injecting bitcast",
15721594 llfn, expected_ty, i, actual_ty
15731595 ) ;
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+ }
15751601 } else {
15761602 actual_val
15771603 }
@@ -1591,7 +1617,7 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
15911617 llfn : & ' ll Value ,
15921618 args : & [ & ' ll Value ] ,
15931619 ) -> & ' 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) ;
15951621
15961622 unsafe {
15971623 llvm:: LLVMBuildCall2 (
@@ -1692,6 +1718,31 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16921718 self . simple_call ( fn_ty, llfn, & [ ptr1, ptr2, num] )
16931719 }
16941720
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+
16951746 pub ( crate ) fn landing_pad (
16961747 & mut self ,
16971748 ty : & ' ll Type ,
@@ -1721,7 +1772,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17211772 ) -> & ' ll Value {
17221773 debug ! ( "invoke {:?} with args ({:?})" , llfn, args) ;
17231774
1724- let args = self . check_call ( "callbr" , llty, llfn, args) ;
1775+ let args = self . cast_arguments ( "callbr" , llty, llfn, args) ;
17251776 let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
17261777 let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
17271778 if let Some ( funclet_bundle) = funclet_bundle {
@@ -1754,8 +1805,10 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17541805 } ;
17551806 if let Some ( fn_abi) = fn_abi {
17561807 fn_abi. apply_attrs_callsite ( self , callbr) ;
1808+ self . cast_return ( fn_abi, llfn, callbr)
1809+ } else {
1810+ callbr
17571811 }
1758- callbr
17591812 }
17601813
17611814 // Emits CFI pointer type membership tests.
0 commit comments