Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -march=x86 | not grep cmov
      2 
      3 ; LSR should be able to eliminate the max computations by
      4 ; making the loops use slt/ult comparisons instead of ne comparisons.
      5 
      6 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
      7 target triple = "i386-apple-darwin9"
      8 
      9 define void @foo(i8* %r, i32 %s, i32 %w, i32 %x, i8* %j, i32 %d) nounwind {
     10 entry:
     11   %0 = mul i32 %x, %w
     12   %1 = mul i32 %x, %w
     13   %2 = sdiv i32 %1, 4
     14   %.sum2 = add i32 %2, %0
     15   %cond = icmp eq i32 %d, 1
     16   br i1 %cond, label %bb29, label %bb10.preheader
     17 
     18 bb10.preheader:                                   ; preds = %entry
     19   %3 = icmp sgt i32 %x, 0
     20   br i1 %3, label %bb.nph9, label %bb18.loopexit
     21 
     22 bb.nph7:                                          ; preds = %bb7.preheader
     23   %4 = mul i32 %y.08, %w
     24   %5 = mul i32 %y.08, %s
     25   %6 = add i32 %5, 1
     26   %tmp8 = icmp sgt i32 1, %w
     27   %smax9 = select i1 %tmp8, i32 1, i32 %w
     28   br label %bb6
     29 
     30 bb6:                                              ; preds = %bb7, %bb.nph7
     31   %x.06 = phi i32 [ 0, %bb.nph7 ], [ %indvar.next7, %bb7 ]
     32   %7 = add i32 %x.06, %4
     33   %8 = shl i32 %x.06, 1
     34   %9 = add i32 %6, %8
     35   %10 = getelementptr i8* %r, i32 %9
     36   %11 = load i8* %10, align 1
     37   %12 = getelementptr i8* %j, i32 %7
     38   store i8 %11, i8* %12, align 1
     39   br label %bb7
     40 
     41 bb7:                                              ; preds = %bb6
     42   %indvar.next7 = add i32 %x.06, 1
     43   %exitcond10 = icmp ne i32 %indvar.next7, %smax9
     44   br i1 %exitcond10, label %bb6, label %bb7.bb9_crit_edge
     45 
     46 bb7.bb9_crit_edge:                                ; preds = %bb7
     47   br label %bb9
     48 
     49 bb9:                                              ; preds = %bb7.preheader, %bb7.bb9_crit_edge
     50   br label %bb10
     51 
     52 bb10:                                             ; preds = %bb9
     53   %indvar.next11 = add i32 %y.08, 1
     54   %exitcond12 = icmp ne i32 %indvar.next11, %x
     55   br i1 %exitcond12, label %bb7.preheader, label %bb10.bb18.loopexit_crit_edge
     56 
     57 bb10.bb18.loopexit_crit_edge:                     ; preds = %bb10
     58   br label %bb10.bb18.loopexit_crit_edge.split
     59 
     60 bb10.bb18.loopexit_crit_edge.split:               ; preds = %bb.nph9, %bb10.bb18.loopexit_crit_edge
     61   br label %bb18.loopexit
     62 
     63 bb.nph9:                                          ; preds = %bb10.preheader
     64   %13 = icmp sgt i32 %w, 0
     65   br i1 %13, label %bb.nph9.split, label %bb10.bb18.loopexit_crit_edge.split
     66 
     67 bb.nph9.split:                                    ; preds = %bb.nph9
     68   br label %bb7.preheader
     69 
     70 bb7.preheader:                                    ; preds = %bb.nph9.split, %bb10
     71   %y.08 = phi i32 [ 0, %bb.nph9.split ], [ %indvar.next11, %bb10 ]
     72   br i1 true, label %bb.nph7, label %bb9
     73 
     74 bb.nph5:                                          ; preds = %bb18.loopexit
     75   %14 = sdiv i32 %w, 2
     76   %15 = icmp slt i32 %w, 2
     77   %16 = sdiv i32 %x, 2
     78   br i1 %15, label %bb18.bb20_crit_edge.split, label %bb.nph5.split
     79 
     80 bb.nph5.split:                                    ; preds = %bb.nph5
     81   %tmp2 = icmp sgt i32 1, %16
     82   %smax3 = select i1 %tmp2, i32 1, i32 %16
     83   br label %bb13
     84 
     85 bb13:                                             ; preds = %bb18, %bb.nph5.split
     86   %y.14 = phi i32 [ 0, %bb.nph5.split ], [ %indvar.next1, %bb18 ]
     87   %17 = mul i32 %14, %y.14
     88   %18 = shl i32 %y.14, 1
     89   %19 = srem i32 %y.14, 2
     90   %20 = add i32 %19, %18
     91   %21 = mul i32 %20, %s
     92   br i1 true, label %bb.nph3, label %bb17
     93 
     94 bb.nph3:                                          ; preds = %bb13
     95   %22 = add i32 %17, %0
     96   %23 = add i32 %17, %.sum2
     97   %24 = sdiv i32 %w, 2
     98   %tmp = icmp sgt i32 1, %24
     99   %smax = select i1 %tmp, i32 1, i32 %24
    100   br label %bb14
    101 
    102 bb14:                                             ; preds = %bb15, %bb.nph3
    103   %x.12 = phi i32 [ 0, %bb.nph3 ], [ %indvar.next, %bb15 ]
    104   %25 = shl i32 %x.12, 2
    105   %26 = add i32 %25, %21
    106   %27 = getelementptr i8* %r, i32 %26
    107   %28 = load i8* %27, align 1
    108   %.sum = add i32 %22, %x.12
    109   %29 = getelementptr i8* %j, i32 %.sum
    110   store i8 %28, i8* %29, align 1
    111   %30 = shl i32 %x.12, 2
    112   %31 = or i32 %30, 2
    113   %32 = add i32 %31, %21
    114   %33 = getelementptr i8* %r, i32 %32
    115   %34 = load i8* %33, align 1
    116   %.sum6 = add i32 %23, %x.12
    117   %35 = getelementptr i8* %j, i32 %.sum6
    118   store i8 %34, i8* %35, align 1
    119   br label %bb15
    120 
    121 bb15:                                             ; preds = %bb14
    122   %indvar.next = add i32 %x.12, 1
    123   %exitcond = icmp ne i32 %indvar.next, %smax
    124   br i1 %exitcond, label %bb14, label %bb15.bb17_crit_edge
    125 
    126 bb15.bb17_crit_edge:                              ; preds = %bb15
    127   br label %bb17
    128 
    129 bb17:                                             ; preds = %bb15.bb17_crit_edge, %bb13
    130   br label %bb18
    131 
    132 bb18.loopexit:                                    ; preds = %bb10.bb18.loopexit_crit_edge.split, %bb10.preheader
    133   %36 = icmp slt i32 %x, 2
    134   br i1 %36, label %bb20, label %bb.nph5
    135 
    136 bb18:                                             ; preds = %bb17
    137   %indvar.next1 = add i32 %y.14, 1
    138   %exitcond4 = icmp ne i32 %indvar.next1, %smax3
    139   br i1 %exitcond4, label %bb13, label %bb18.bb20_crit_edge
    140 
    141 bb18.bb20_crit_edge:                              ; preds = %bb18
    142   br label %bb18.bb20_crit_edge.split
    143 
    144 bb18.bb20_crit_edge.split:                        ; preds = %bb18.bb20_crit_edge, %bb.nph5
    145   br label %bb20
    146 
    147 bb20:                                             ; preds = %bb18.bb20_crit_edge.split, %bb18.loopexit
    148   switch i32 %d, label %return [
    149     i32 3, label %bb22
    150     i32 1, label %bb29
    151   ]
    152 
    153 bb22:                                             ; preds = %bb20
    154   %37 = mul i32 %x, %w
    155   %38 = sdiv i32 %37, 4
    156   %.sum3 = add i32 %38, %.sum2
    157   %39 = add i32 %x, 15
    158   %40 = and i32 %39, -16
    159   %41 = add i32 %w, 15
    160   %42 = and i32 %41, -16
    161   %43 = mul i32 %40, %s
    162   %44 = icmp sgt i32 %x, 0
    163   br i1 %44, label %bb.nph, label %bb26
    164 
    165 bb.nph:                                           ; preds = %bb22
    166   br label %bb23
    167 
    168 bb23:                                             ; preds = %bb24, %bb.nph
    169   %y.21 = phi i32 [ 0, %bb.nph ], [ %indvar.next5, %bb24 ]
    170   %45 = mul i32 %y.21, %42
    171   %.sum1 = add i32 %45, %43
    172   %46 = getelementptr i8* %r, i32 %.sum1
    173   %47 = mul i32 %y.21, %w
    174   %.sum5 = add i32 %47, %.sum3
    175   %48 = getelementptr i8* %j, i32 %.sum5
    176   tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %48, i8* %46, i32 %w, i32 1, i1 false)
    177   br label %bb24
    178 
    179 bb24:                                             ; preds = %bb23
    180   %indvar.next5 = add i32 %y.21, 1
    181   %exitcond6 = icmp ne i32 %indvar.next5, %x
    182   br i1 %exitcond6, label %bb23, label %bb24.bb26_crit_edge
    183 
    184 bb24.bb26_crit_edge:                              ; preds = %bb24
    185   br label %bb26
    186 
    187 bb26:                                             ; preds = %bb24.bb26_crit_edge, %bb22
    188   %49 = mul i32 %x, %w
    189   %.sum4 = add i32 %.sum3, %49
    190   %50 = getelementptr i8* %j, i32 %.sum4
    191   %51 = mul i32 %x, %w
    192   %52 = sdiv i32 %51, 2
    193   tail call void @llvm.memset.p0i8.i32(i8* %50, i8 -128, i32 %52, i32 1, i1 false)
    194   ret void
    195 
    196 bb29:                                             ; preds = %bb20, %entry
    197   %53 = add i32 %w, 15
    198   %54 = and i32 %53, -16
    199   %55 = icmp sgt i32 %x, 0
    200   br i1 %55, label %bb.nph11, label %bb33
    201 
    202 bb.nph11:                                         ; preds = %bb29
    203   br label %bb30
    204 
    205 bb30:                                             ; preds = %bb31, %bb.nph11
    206   %y.310 = phi i32 [ 0, %bb.nph11 ], [ %indvar.next13, %bb31 ]
    207   %56 = mul i32 %y.310, %54
    208   %57 = getelementptr i8* %r, i32 %56
    209   %58 = mul i32 %y.310, %w
    210   %59 = getelementptr i8* %j, i32 %58
    211   tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %59, i8* %57, i32 %w, i32 1, i1 false)
    212   br label %bb31
    213 
    214 bb31:                                             ; preds = %bb30
    215   %indvar.next13 = add i32 %y.310, 1
    216   %exitcond14 = icmp ne i32 %indvar.next13, %x
    217   br i1 %exitcond14, label %bb30, label %bb31.bb33_crit_edge
    218 
    219 bb31.bb33_crit_edge:                              ; preds = %bb31
    220   br label %bb33
    221 
    222 bb33:                                             ; preds = %bb31.bb33_crit_edge, %bb29
    223   %60 = mul i32 %x, %w
    224   %61 = getelementptr i8* %j, i32 %60
    225   %62 = mul i32 %x, %w
    226   %63 = sdiv i32 %62, 2
    227   tail call void @llvm.memset.p0i8.i32(i8* %61, i8 -128, i32 %63, i32 1, i1 false)
    228   ret void
    229 
    230 return:                                           ; preds = %bb20
    231   ret void
    232 }
    233 
    234 define void @bar(i8* %r, i32 %s, i32 %w, i32 %x, i8* %j, i32 %d) nounwind {
    235 entry:
    236   %0 = mul i32 %x, %w
    237   %1 = mul i32 %x, %w
    238   %2 = udiv i32 %1, 4
    239   %.sum2 = add i32 %2, %0
    240   %cond = icmp eq i32 %d, 1
    241   br i1 %cond, label %bb29, label %bb10.preheader
    242 
    243 bb10.preheader:                                   ; preds = %entry
    244   %3 = icmp ne i32 %x, 0
    245   br i1 %3, label %bb.nph9, label %bb18.loopexit
    246 
    247 bb.nph7:                                          ; preds = %bb7.preheader
    248   %4 = mul i32 %y.08, %w
    249   %5 = mul i32 %y.08, %s
    250   %6 = add i32 %5, 1
    251   %tmp8 = icmp ugt i32 1, %w
    252   %smax9 = select i1 %tmp8, i32 1, i32 %w
    253   br label %bb6
    254 
    255 bb6:                                              ; preds = %bb7, %bb.nph7
    256   %x.06 = phi i32 [ 0, %bb.nph7 ], [ %indvar.next7, %bb7 ]
    257   %7 = add i32 %x.06, %4
    258   %8 = shl i32 %x.06, 1
    259   %9 = add i32 %6, %8
    260   %10 = getelementptr i8* %r, i32 %9
    261   %11 = load i8* %10, align 1
    262   %12 = getelementptr i8* %j, i32 %7
    263   store i8 %11, i8* %12, align 1
    264   br label %bb7
    265 
    266 bb7:                                              ; preds = %bb6
    267   %indvar.next7 = add i32 %x.06, 1
    268   %exitcond10 = icmp ne i32 %indvar.next7, %smax9
    269   br i1 %exitcond10, label %bb6, label %bb7.bb9_crit_edge
    270 
    271 bb7.bb9_crit_edge:                                ; preds = %bb7
    272   br label %bb9
    273 
    274 bb9:                                              ; preds = %bb7.preheader, %bb7.bb9_crit_edge
    275   br label %bb10
    276 
    277 bb10:                                             ; preds = %bb9
    278   %indvar.next11 = add i32 %y.08, 1
    279   %exitcond12 = icmp ne i32 %indvar.next11, %x
    280   br i1 %exitcond12, label %bb7.preheader, label %bb10.bb18.loopexit_crit_edge
    281 
    282 bb10.bb18.loopexit_crit_edge:                     ; preds = %bb10
    283   br label %bb10.bb18.loopexit_crit_edge.split
    284 
    285 bb10.bb18.loopexit_crit_edge.split:               ; preds = %bb.nph9, %bb10.bb18.loopexit_crit_edge
    286   br label %bb18.loopexit
    287 
    288 bb.nph9:                                          ; preds = %bb10.preheader
    289   %13 = icmp ugt i32 %w, 0
    290   br i1 %13, label %bb.nph9.split, label %bb10.bb18.loopexit_crit_edge.split
    291 
    292 bb.nph9.split:                                    ; preds = %bb.nph9
    293   br label %bb7.preheader
    294 
    295 bb7.preheader:                                    ; preds = %bb.nph9.split, %bb10
    296   %y.08 = phi i32 [ 0, %bb.nph9.split ], [ %indvar.next11, %bb10 ]
    297   br i1 true, label %bb.nph7, label %bb9
    298 
    299 bb.nph5:                                          ; preds = %bb18.loopexit
    300   %14 = udiv i32 %w, 2
    301   %15 = icmp ult i32 %w, 2
    302   %16 = udiv i32 %x, 2
    303   br i1 %15, label %bb18.bb20_crit_edge.split, label %bb.nph5.split
    304 
    305 bb.nph5.split:                                    ; preds = %bb.nph5
    306   %tmp2 = icmp ugt i32 1, %16
    307   %smax3 = select i1 %tmp2, i32 1, i32 %16
    308   br label %bb13
    309 
    310 bb13:                                             ; preds = %bb18, %bb.nph5.split
    311   %y.14 = phi i32 [ 0, %bb.nph5.split ], [ %indvar.next1, %bb18 ]
    312   %17 = mul i32 %14, %y.14
    313   %18 = shl i32 %y.14, 1
    314   %19 = urem i32 %y.14, 2
    315   %20 = add i32 %19, %18
    316   %21 = mul i32 %20, %s
    317   br i1 true, label %bb.nph3, label %bb17
    318 
    319 bb.nph3:                                          ; preds = %bb13
    320   %22 = add i32 %17, %0
    321   %23 = add i32 %17, %.sum2
    322   %24 = udiv i32 %w, 2
    323   %tmp = icmp ugt i32 1, %24
    324   %smax = select i1 %tmp, i32 1, i32 %24
    325   br label %bb14
    326 
    327 bb14:                                             ; preds = %bb15, %bb.nph3
    328   %x.12 = phi i32 [ 0, %bb.nph3 ], [ %indvar.next, %bb15 ]
    329   %25 = shl i32 %x.12, 2
    330   %26 = add i32 %25, %21
    331   %27 = getelementptr i8* %r, i32 %26
    332   %28 = load i8* %27, align 1
    333   %.sum = add i32 %22, %x.12
    334   %29 = getelementptr i8* %j, i32 %.sum
    335   store i8 %28, i8* %29, align 1
    336   %30 = shl i32 %x.12, 2
    337   %31 = or i32 %30, 2
    338   %32 = add i32 %31, %21
    339   %33 = getelementptr i8* %r, i32 %32
    340   %34 = load i8* %33, align 1
    341   %.sum6 = add i32 %23, %x.12
    342   %35 = getelementptr i8* %j, i32 %.sum6
    343   store i8 %34, i8* %35, align 1
    344   br label %bb15
    345 
    346 bb15:                                             ; preds = %bb14
    347   %indvar.next = add i32 %x.12, 1
    348   %exitcond = icmp ne i32 %indvar.next, %smax
    349   br i1 %exitcond, label %bb14, label %bb15.bb17_crit_edge
    350 
    351 bb15.bb17_crit_edge:                              ; preds = %bb15
    352   br label %bb17
    353 
    354 bb17:                                             ; preds = %bb15.bb17_crit_edge, %bb13
    355   br label %bb18
    356 
    357 bb18.loopexit:                                    ; preds = %bb10.bb18.loopexit_crit_edge.split, %bb10.preheader
    358   %36 = icmp ult i32 %x, 2
    359   br i1 %36, label %bb20, label %bb.nph5
    360 
    361 bb18:                                             ; preds = %bb17
    362   %indvar.next1 = add i32 %y.14, 1
    363   %exitcond4 = icmp ne i32 %indvar.next1, %smax3
    364   br i1 %exitcond4, label %bb13, label %bb18.bb20_crit_edge
    365 
    366 bb18.bb20_crit_edge:                              ; preds = %bb18
    367   br label %bb18.bb20_crit_edge.split
    368 
    369 bb18.bb20_crit_edge.split:                        ; preds = %bb18.bb20_crit_edge, %bb.nph5
    370   br label %bb20
    371 
    372 bb20:                                             ; preds = %bb18.bb20_crit_edge.split, %bb18.loopexit
    373   switch i32 %d, label %return [
    374     i32 3, label %bb22
    375     i32 1, label %bb29
    376   ]
    377 
    378 bb22:                                             ; preds = %bb20
    379   %37 = mul i32 %x, %w
    380   %38 = udiv i32 %37, 4
    381   %.sum3 = add i32 %38, %.sum2
    382   %39 = add i32 %x, 15
    383   %40 = and i32 %39, -16
    384   %41 = add i32 %w, 15
    385   %42 = and i32 %41, -16
    386   %43 = mul i32 %40, %s
    387   %44 = icmp ugt i32 %x, 0
    388   br i1 %44, label %bb.nph, label %bb26
    389 
    390 bb.nph:                                           ; preds = %bb22
    391   br label %bb23
    392 
    393 bb23:                                             ; preds = %bb24, %bb.nph
    394   %y.21 = phi i32 [ 0, %bb.nph ], [ %indvar.next5, %bb24 ]
    395   %45 = mul i32 %y.21, %42
    396   %.sum1 = add i32 %45, %43
    397   %46 = getelementptr i8* %r, i32 %.sum1
    398   %47 = mul i32 %y.21, %w
    399   %.sum5 = add i32 %47, %.sum3
    400   %48 = getelementptr i8* %j, i32 %.sum5
    401   tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %48, i8* %46, i32 %w, i32 1, i1 false)
    402   br label %bb24
    403 
    404 bb24:                                             ; preds = %bb23
    405   %indvar.next5 = add i32 %y.21, 1
    406   %exitcond6 = icmp ne i32 %indvar.next5, %x
    407   br i1 %exitcond6, label %bb23, label %bb24.bb26_crit_edge
    408 
    409 bb24.bb26_crit_edge:                              ; preds = %bb24
    410   br label %bb26
    411 
    412 bb26:                                             ; preds = %bb24.bb26_crit_edge, %bb22
    413   %49 = mul i32 %x, %w
    414   %.sum4 = add i32 %.sum3, %49
    415   %50 = getelementptr i8* %j, i32 %.sum4
    416   %51 = mul i32 %x, %w
    417   %52 = udiv i32 %51, 2
    418   tail call void @llvm.memset.p0i8.i32(i8* %50, i8 -128, i32 %52, i32 1, i1 false)
    419   ret void
    420 
    421 bb29:                                             ; preds = %bb20, %entry
    422   %53 = add i32 %w, 15
    423   %54 = and i32 %53, -16
    424   %55 = icmp ugt i32 %x, 0
    425   br i1 %55, label %bb.nph11, label %bb33
    426 
    427 bb.nph11:                                         ; preds = %bb29
    428   br label %bb30
    429 
    430 bb30:                                             ; preds = %bb31, %bb.nph11
    431   %y.310 = phi i32 [ 0, %bb.nph11 ], [ %indvar.next13, %bb31 ]
    432   %56 = mul i32 %y.310, %54
    433   %57 = getelementptr i8* %r, i32 %56
    434   %58 = mul i32 %y.310, %w
    435   %59 = getelementptr i8* %j, i32 %58
    436   tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %59, i8* %57, i32 %w, i32 1, i1 false)
    437   br label %bb31
    438 
    439 bb31:                                             ; preds = %bb30
    440   %indvar.next13 = add i32 %y.310, 1
    441   %exitcond14 = icmp ne i32 %indvar.next13, %x
    442   br i1 %exitcond14, label %bb30, label %bb31.bb33_crit_edge
    443 
    444 bb31.bb33_crit_edge:                              ; preds = %bb31
    445   br label %bb33
    446 
    447 bb33:                                             ; preds = %bb31.bb33_crit_edge, %bb29
    448   %60 = mul i32 %x, %w
    449   %61 = getelementptr i8* %j, i32 %60
    450   %62 = mul i32 %x, %w
    451   %63 = udiv i32 %62, 2
    452   tail call void @llvm.memset.p0i8.i32(i8* %61, i8 -128, i32 %63, i32 1, i1 false)
    453   ret void
    454 
    455 return:                                           ; preds = %bb20
    456   ret void
    457 }
    458 
    459 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
    460 
    461 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
    462