//===----------------------------------------------------------------------===//// Representing sign/zero extension of function results//===----------------------------------------------------------------------===//Mar25,2009-InitialRevisionMostABIsspecifythatfunctionswhichreturnsmallintegersdosoinaspecificintegerGPR.Thisisanefficientwaytogo,butraisesthequestion:ifthereturnedvalueissmallerthantheregister,whatdothehighbitshold?Therearethree(interesting)possibleanswers:undefined,zeroextended,orsignextended.Thenumberofbitsinquestiondependsonthedata-typethatthefront-endisreferencing(typicallyi1/i8/i16/i32).Knowingtheanswertothisisimportantfortworeasons:1)wewanttobeabletoimplementtheABIcorrectly.IfweneedtosignextendtheresultaccordingtotheABI,wereallyreallydoneedtodothistopreservecorrectness.2)thisinformationisoftenusefulforoptimizationpurposes,andwewantthemid-leveloptimizerstobeabletoprocessthis(e.g.eliminateredundantextensions).Forexample,letspretendthatX86requiresthecallertoproperlyextendtheresultofareturn(I'mnotsurethisisthecase,buttheargumentdoesn'tdependonthis).Giventhis,weshouldcompilethis:inta();shortb(){returna();}into:_b:subl$12,%espcallL_a$stubaddl$12,%espcwtlretAnoptimizationexampleisthatweshouldbeabletoeliminatetheexplicitsignextensioninthisexample:shorty();intz(){return((int)y()<<16)>>16;}_z:subl$12,%espcall_y;;movswl%ax,%eax->notneededbecauseeaxisalreadysext'daddl$12,%espret//===----------------------------------------------------------------------===//// What we have right now.//===----------------------------------------------------------------------===//Currently,thesesortsofthingsaremodelledbycompilingafunctiontoreturnthesmalltypeandasignext/zeroextmarkerisused.Forexample,wecompileZinto:definei32@z()nounwind{entry:%0=tailcallsignexti16(...)*@y()nounwind%1=sexti16%0toi32reti32%1}andbinto:definesignexti16@b()nounwind{entry:%0=tailcalli32(...)*@a()nounwind;<i32>[#uses=1]%retval12=trunci32%0toi16;<i16>[#uses=1]reti16%retval12}Thishassomeproblems:1)theactualprecisesemanticsarereallypoorlydefined(seePR3779).2)sometargetsmightwantthecallertoextend,somemightwantthecalleetoextend3)themid-leveloptimizerdoesn'tknowthesizeoftheGPR,soitdoesn'tknowthat%0issignextendedupto32-bitshere,andevenifitdid,itcouldnoteliminatethesext.4)thecodegeneratorhashistoricallyassumedthattheresultisextendedtoi32,whichisaproblemonPIC16(andisalsoprobablywrongonalphaandother64-bittargets).//===----------------------------------------------------------------------===//// The proposal//===----------------------------------------------------------------------===//Isuggestthatwehavethefront-endfullylowerouttheABIissuesheretoLLVMIR.Thismakesit100%explicitwhatisgoingonandmeansthatthereisnocauseforconfusion.Forexample,thecasesaboveshouldcompileinto:definei32@z()nounwind{entry:%0=tailcalli32(...)*@y()nounwind%1=trunci32%0toi16%2=sexti16%1toi32reti32%2}definei32@b()nounwind{entry:%0=tailcalli32(...)*@a()nounwind%retval12=trunci32%0toi16%tmp=sexti16%retval12toi32reti32%tmp}Inthismodel,nofunctionswillreturnani1/i8/i16(andonax86-64targetthatextendsresultstoi64,noi32).Thissolvestheambiguityissue,allowsustofullydescribeallpossibleABIs,andnowallowstheoptimizerstoreasonaboutandeliminatetheseextensions.Theonethingthatismissingistheabilityforthefront-endandoptimizertospecify/infertheguaranteesprovidedbytheABItoallowotheroptimizations.Forexample,inthey/zcase,sinceyisknowntoreturnasignextendedvalue,thetrunc/sextinzshouldbeeliminable.Thiscanbedonebyintroducingnewsext/zextattributeswhichmean"I knowthat the result of the function is sign extended at least N bits. Given this,and given that it is stuck on the y function, the mid-level optimizer couldeasily eliminate the extensions etc with existing functionality.The major disadvantage of doing this sort of thing is that it makes the ABIlowering stuff even more explicit in the front-end, and that we would like toeventually move to having the code generator do more of this work. However,the sad truth of the matter is that this is a) unlikely to happen anytime inthe near future, and b) this is no worse than we have now with the existingattributes.C compilers fundamentally have to reason about the target in many ways. This is ugly and horrible, but a fact of life.