1//===----------------------------------------------------------------------===// 2// Representing sign/zero extension of function results 3//===----------------------------------------------------------------------===// 4 5Mar 25, 2009 - Initial Revision 6 7Most ABIs specify that functions which return small integers do so in a 8specific integer GPR. This is an efficient way to go, but raises the question: 9if the returned value is smaller than the register, what do the high bits hold? 10 11There are three (interesting) possible answers: undefined, zero extended, or 12sign extended. The number of bits in question depends on the data-type that 13the front-end is referencing (typically i1/i8/i16/i32). 14 15Knowing the answer to this is important for two reasons: 1) we want to be able 16to implement the ABI correctly. If we need to sign extend the result according 17to the ABI, we really really do need to do this to preserve correctness. 2) 18this information is often useful for optimization purposes, and we want the 19mid-level optimizers to be able to process this (e.g. eliminate redundant 20extensions). 21 22For example, lets pretend that X86 requires the caller to properly extend the 23result of a return (I'm not sure this is the case, but the argument doesn't 24depend on this). Given this, we should compile this: 25 26int a(); 27short b() { return a(); } 28 29into: 30 31_b: 32 subl $12, %esp 33 call L_a$stub 34 addl $12, %esp 35 cwtl 36 ret 37 38An optimization example is that we should be able to eliminate the explicit 39sign extension in this example: 40 41short y(); 42int z() { 43 return ((int)y() << 16) >> 16; 44} 45 46_z: 47 subl $12, %esp 48 call _y 49 ;; movswl %ax, %eax -> not needed because eax is already sext'd 50 addl $12, %esp 51 ret 52 53//===----------------------------------------------------------------------===// 54// What we have right now. 55//===----------------------------------------------------------------------===// 56 57Currently, these sorts of things are modelled by compiling a function to return 58the small type and a signext/zeroext marker is used. For example, we compile 59Z into: 60 61define i32 @z() nounwind { 62entry: 63 %0 = tail call signext i16 (...)* @y() nounwind 64 %1 = sext i16 %0 to i32 65 ret i32 %1 66} 67 68and b into: 69 70define signext i16 @b() nounwind { 71entry: 72 %0 = tail call i32 (...)* @a() nounwind ; <i32> [#uses=1] 73 %retval12 = trunc i32 %0 to i16 ; <i16> [#uses=1] 74 ret i16 %retval12 75} 76 77This has some problems: 1) the actual precise semantics are really poorly 78defined (see PR3779). 2) some targets might want the caller to extend, some 79might want the callee to extend 3) the mid-level optimizer doesn't know the 80size of the GPR, so it doesn't know that %0 is sign extended up to 32-bits 81here, and even if it did, it could not eliminate the sext. 4) the code 82generator has historically assumed that the result is extended to i32, which is 83a problem on PIC16 (and is also probably wrong on alpha and other 64-bit 84targets). 85 86//===----------------------------------------------------------------------===// 87// The proposal 88//===----------------------------------------------------------------------===// 89 90I suggest that we have the front-end fully lower out the ABI issues here to 91LLVM IR. This makes it 100% explicit what is going on and means that there is 92no cause for confusion. For example, the cases above should compile into: 93 94define i32 @z() nounwind { 95entry: 96 %0 = tail call i32 (...)* @y() nounwind 97 %1 = trunc i32 %0 to i16 98 %2 = sext i16 %1 to i32 99 ret i32 %2 100} 101define i32 @b() nounwind { 102entry: 103 %0 = tail call i32 (...)* @a() nounwind 104 %retval12 = trunc i32 %0 to i16 105 %tmp = sext i16 %retval12 to i32 106 ret i32 %tmp 107} 108 109In this model, no functions will return an i1/i8/i16 (and on a x86-64 target 110that extends results to i64, no i32). This solves the ambiguity issue, allows us 111to fully describe all possible ABIs, and now allows the optimizers to reason 112about and eliminate these extensions. 113 114The one thing that is missing is the ability for the front-end and optimizer to 115specify/infer the guarantees provided by the ABI to allow other optimizations. 116For example, in the y/z case, since y is known to return a sign extended value, 117the trunc/sext in z should be eliminable. 118 119This can be done by introducing new sext/zext attributes which mean "I know 120that the result of the function is sign extended at least N bits. Given this, 121and given that it is stuck on the y function, the mid-level optimizer could 122easily eliminate the extensions etc with existing functionality. 123 124The major disadvantage of doing this sort of thing is that it makes the ABI 125lowering stuff even more explicit in the front-end, and that we would like to 126eventually move to having the code generator do more of this work. However, 127the sad truth of the matter is that this is a) unlikely to happen anytime in 128the near future, and b) this is no worse than we have now with the existing 129attributes. 130 131C compilers fundamentally have to reason about the target in many ways. 132This is ugly and horrible, but a fact of life. 133 134