[llvm-commits] llvm-gcc: emit switch cases with a wide range as a conditional branch

Duncan Sands baldrick at free.fr
Mon Mar 12 13:48:38 PDT 2007


In gcc, a switch case is a range of values that branch
to a label, for example 1 .. 17 -> label.  These are
emitted as individual LLVM switch cases: 1 -> label,
2 -> label, ..., 17 -> label.  This works well except,
for example, when the range is INT_MIN .. 0 -> label,
in which case you can say goodbye to all your memory!
This patch causes ranges with more than 64 elements
(128 on 64 bit machines) to be emitted as explicit "if"
statements.  For example, the following gcc switch
(from the Ada testcase)

  INT_MIN .. -1 -> block_neg
  0 -> block_zero
  default -> block_default

is emitted as
        switch i32 %n, label %0 [
                 i32 0, label %block_zero
        ]

; <label>:0             ; preds = %entry
        %tmp = sub i32 %n, -2147483648              ; <i32> [#uses=1]
        icmp ule i32 %tmp, 2147483647          ; <i1>:2 [#uses=1]
        br i1 %2, label %block_neg, label %case_false

case_false:             ; preds = %0
        br label %block_default

The "if" statements are placed in the default block of the switch,
with a branch to the real default label if none of them fires.

Ciao,

Duncan.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: switch.diff
Type: text/x-diff
Size: 2783 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20070312/43cf43cd/attachment.diff>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: switch-test.diff
Type: text/x-diff
Size: 524 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20070312/43cf43cd/attachment-0001.diff>


More information about the llvm-commits mailing list