Vikram S. Adve | 9bf6546 | 2001-09-18 13:10:26 +0000 | [diff] [blame] | 1 | implementation |
| 2 | |
| 3 | ; A SetCC whose result is used should produce instructions to |
| 4 | ; compute the boolean value in a register. One whose result |
| 5 | ; is unused will only generate the condition code but not |
| 6 | ; the boolean result. |
| 7 | ; |
| 8 | void "unusedBool"(int * %x, int * %y) |
| 9 | begin |
| 10 | ; <label>:0 ; [#uses=0] |
| 11 | seteq int * %x, %y ; <bool>:0 [#uses=1] |
| 12 | not bool %0 ; <bool>:1 [#uses=0] |
| 13 | setne int * %x, %y ; <bool>:2 [#uses=0] |
| 14 | ret void |
| 15 | end |
| 16 | |
| 17 | ; A constant argument to a Phi produces a Cast instruction in the |
| 18 | ; corresponding predecessor basic block. This has little to do with |
| 19 | ; selection but the code is a bit weird. |
| 20 | ; |
| 21 | void "mergeConstants"(int * %x, int * %y) |
| 22 | begin |
| 23 | ; <label>:0 ; [#uses=1] |
| 24 | br label %Top |
| 25 | Top: ; [#uses=4] |
| 26 | phi int [ 0, %0 ], [ 1, %Top ], [ 2, %Next ] ; <int>:0 [#uses=0] |
| 27 | br bool true, label %Top, label %Next |
| 28 | Next: ; [#uses=2] |
| 29 | br label %Top |
| 30 | end |
| 31 | |
| 32 | |
| 33 | ; Test branch-on-comparison-with-zero, in two ways: |
| 34 | ; 1. can be folded |
| 35 | ; 2. cannot be folded because result of comparison is used twice |
| 36 | ; |
| 37 | void "testbool"(int, int) ; Def %0, %1 |
| 38 | int 0 ; Def 2 |
| 39 | int -4 ; Def 3 |
| 40 | begin |
| 41 | add int %0, %1 ; Def 4 |
| 42 | sub int %4, %3 ; Def 5 |
| 43 | setle int %5, %2 ; Def 0 - bool plane |
| 44 | br bool %0, label %retlbl, label %loop |
| 45 | |
| 46 | loop: |
| 47 | add int %0, %1 ; Def 6 |
| 48 | sub int %4, %3 ; Def 7 |
| 49 | setle int %7, %2 ; Def 1 - bool |
| 50 | not bool %1 ; Def 2 - bool. first use of bool %1 |
| 51 | br bool %1, label %loop, label %0 ; second use of bool %1 |
| 52 | |
| 53 | retlbl: |
| 54 | ret void |
| 55 | end |
| 56 | |
| 57 | |
| 58 | ; Test branch on floating point comparison |
| 59 | ; |
| 60 | void "testfloatbool"(float %x, float %y) ; Def %0, %1 - float |
| 61 | begin |
| 62 | %p = add float %x, %y ; Def 2 - float |
| 63 | %z = sub float %x, %y ; Def 3 - float |
| 64 | %b = setle float %p, %z ; Def 0 - bool |
| 65 | %c = not bool %b ; Def 1 - bool |
| 66 | br bool %b, label %0, label %goon |
| 67 | goon: |
| 68 | ret void |
| 69 | end |
| 70 | |
| 71 | |
| 72 | ; Test cases where an LLVM instruction requires no machine |
| 73 | ; instructions (e.g., cast int* to long). But there are 2 cases: |
| 74 | ; 1. If the result register has only a single use, the operand will be |
| 75 | ; copy-propagated during instruction selection. |
| 76 | ; 2. If the result register has multiple uses, it cannot be copy |
| 77 | ; propagated during instruction selection. It will generate a |
| 78 | ; copy instruction (add-with-0), but this copy should get coalesced |
| 79 | ; away by the register allocator. |
| 80 | ; |
| 81 | int "checkForward"(int %N, int* %A) |
| 82 | begin |
| 83 | |
| 84 | bb2: ;;<label> |
| 85 | %reg114 = shl int %N, ubyte 2 ;; |
| 86 | %cast115 = cast int %reg114 to int* ;; reg114 will be propagated |
| 87 | %reg116 = add int* %A, %cast115 ;; |
| 88 | %reg118 = load int* %reg116 ;; |
| 89 | %cast117 = cast int %reg118 to long ;; reg118 will be copied 'cos |
| 90 | %reg159 = add long 1234567, %cast117 ;; cast117 has 2 uses, here |
| 91 | %reg160 = add long 7654321, %cast117 ;; and here. |
| 92 | ret void |
| 93 | end |