Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt -instcombine -S  < %s | FileCheck %s
      2 
      3 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:64"
      4 
      5 define i32 *@test1(i32* %A, i32 %Offset) {
      6 entry:
      7   %tmp = getelementptr inbounds i32, i32* %A, i32 %Offset
      8   br label %bb
      9 
     10 bb:
     11   %RHS = phi i32* [ %RHS.next, %bb ], [ %tmp, %entry ]
     12   %LHS = getelementptr inbounds i32, i32* %A, i32 100
     13   %RHS.next = getelementptr inbounds i32, i32* %RHS, i64 1
     14   %cond = icmp ult i32 * %LHS, %RHS
     15   br i1 %cond, label %bb2, label %bb
     16 
     17 bb2:
     18   ret i32* %RHS
     19 
     20 ; CHECK-LABEL: @test1(
     21 ; CHECK:  %[[INDEX:[0-9A-Za-z.]+]] = phi i32 [ %[[ADD:[0-9A-Za-z.]+]], %bb ], [ %Offset, %entry ]
     22 ; CHECK:  %[[ADD]] = add nsw i32 %[[INDEX]], 1
     23 ; CHECK:  %cond = icmp sgt i32 %[[INDEX]], 100
     24 ; CHECK:  br i1 %cond, label %bb2, label %bb
     25 ; CHECK:  %[[PTR:[0-9A-Za-z.]+]] = getelementptr inbounds i32, i32* %A, i32 %[[INDEX]]
     26 ; CHECK:  ret i32* %[[PTR]]
     27 }
     28 
     29 define i32 *@test2(i32 %A, i32 %Offset) {
     30 entry:
     31   %A.ptr = inttoptr i32 %A to i32*
     32   %tmp = getelementptr inbounds i32, i32* %A.ptr, i32 %Offset
     33   br label %bb
     34 
     35 bb:
     36   %RHS = phi i32* [ %RHS.next, %bb ], [ %tmp, %entry ]
     37   %LHS = getelementptr inbounds i32, i32* %A.ptr, i32 100
     38   %RHS.next = getelementptr inbounds i32, i32* %RHS, i64 1
     39   %cmp0 = ptrtoint i32 *%LHS to i32
     40   %cmp1 = ptrtoint i32 *%RHS to i32
     41   %cond = icmp ult i32 %cmp0, %cmp1
     42   br i1 %cond, label %bb2, label %bb
     43 
     44 bb2:
     45   ret i32* %RHS
     46 
     47 ; CHECK-LABEL: @test2(
     48 ; CHECK:  %[[INDEX:[0-9A-Za-z.]+]] = phi i32 [ %[[ADD:[0-9A-Za-z.]+]], %bb ], [ %Offset, %entry ]
     49 ; CHECK:  %[[ADD]] = add nsw i32 %[[INDEX]], 1
     50 ; CHECK:  %cond = icmp sgt i32 %[[INDEX]], 100
     51 ; CHECK:  br i1 %cond, label %bb2, label %bb
     52 ; CHECK:  %[[TOPTR:[0-9A-Za-z.]+]] = inttoptr i32 %[[ADD:[0-9A-Za-z.]+]] to i32*
     53 ; CHECK:  %[[PTR:[0-9A-Za-z.]+]] = getelementptr inbounds i32, i32* %[[TOPTR]], i32 %[[INDEX]]
     54 ; CHECK:  ret i32* %[[PTR]]
     55 }
     56 
     57 ; Perform the transformation only if we know that the GEPs used are inbounds.
     58 define i32 *@test3(i32* %A, i32 %Offset) {
     59 entry:
     60   %tmp = getelementptr i32, i32* %A, i32 %Offset
     61   br label %bb
     62 
     63 bb:
     64   %RHS = phi i32* [ %RHS.next, %bb ], [ %tmp, %entry ]
     65   %LHS = getelementptr i32, i32* %A, i32 100
     66   %RHS.next = getelementptr i32, i32* %RHS, i64 1
     67   %cond = icmp ult i32 * %LHS, %RHS
     68   br i1 %cond, label %bb2, label %bb
     69 
     70 bb2:
     71   ret i32* %RHS
     72 
     73 ; CHECK-LABEL: @test3(
     74 ; CHECK-NOT:  %cond = icmp sgt i32 %{{[0-9A-Za-z.]+}}, 100
     75 }
     76 
     77 ; An inttoptr that requires an extension or truncation will be opaque when determining
     78 ; the base pointer. In this case we can still perform the transformation by considering
     79 ; A.ptr as being the base pointer.
     80 define i32 *@test4(i16 %A, i32 %Offset) {
     81 entry:
     82   %A.ptr = inttoptr i16 %A to i32*
     83   %tmp = getelementptr inbounds i32, i32* %A.ptr, i32 %Offset
     84   br label %bb
     85 
     86 bb:
     87   %RHS = phi i32* [ %RHS.next, %bb ], [ %tmp, %entry ]
     88   %LHS = getelementptr inbounds i32, i32* %A.ptr, i32 100
     89   %RHS.next = getelementptr inbounds i32, i32* %RHS, i64 1
     90   %cmp0 = ptrtoint i32 *%LHS to i32
     91   %cmp1 = ptrtoint i32 *%RHS to i32
     92   %cond = icmp ult i32 %cmp0, %cmp1
     93   br i1 %cond, label %bb2, label %bb
     94 
     95 bb2:
     96   ret i32* %RHS
     97 
     98 ; CHECK-LABEL: @test4(
     99 ; CHECK:  %cond = icmp sgt i32 %{{[0-9A-Za-z.]+}}, 100
    100 }
    101 
    102 declare i32* @fun_ptr()
    103 
    104 define i32 *@test5(i32 %Offset) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    105 entry:
    106  %A = invoke i32 *@fun_ptr() to label %cont unwind label %lpad
    107 
    108 cont:
    109   %tmp = getelementptr inbounds i32, i32* %A, i32 %Offset
    110   br label %bb
    111 
    112 bb:
    113   %RHS = phi i32* [ %RHS.next, %bb ], [ %tmp, %cont ]
    114   %LHS = getelementptr inbounds i32, i32* %A, i32 100
    115   %RHS.next = getelementptr inbounds i32, i32* %RHS, i64 1
    116   %cond = icmp ult i32 * %LHS, %RHS
    117   br i1 %cond, label %bb2, label %bb
    118 
    119 bb2:
    120   ret i32* %RHS
    121 
    122 lpad:
    123   %l = landingpad { i8*, i32 } cleanup
    124   ret i32* null
    125 
    126 ; CHECK-LABEL: @test5(
    127 ; CHECK:  %[[INDEX:[0-9A-Za-z.]+]] = phi i32 [ %[[ADD:[0-9A-Za-z.]+]], %bb ], [ %Offset, %cont ]
    128 ; CHECK:  %[[ADD]] = add nsw i32 %[[INDEX]], 1
    129 ; CHECK:  %cond = icmp sgt i32 %[[INDEX]], 100
    130 ; CHECK:  br i1 %cond, label %bb2, label %bb
    131 ; CHECK:  %[[PTR:[0-9A-Za-z.]+]] = getelementptr inbounds i32, i32* %A, i32 %[[INDEX]]
    132 ; CHECK:  ret i32* %[[PTR]]
    133 }
    134 
    135 declare i32 @fun_i32()
    136 
    137 define i32 *@test6(i32 %Offset) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    138 entry:
    139  %A = invoke i32 @fun_i32() to label %cont unwind label %lpad
    140 
    141 cont:
    142   %A.ptr = inttoptr i32 %A to i32*
    143   %tmp = getelementptr inbounds i32, i32* %A.ptr, i32 %Offset
    144   br label %bb
    145 
    146 bb:
    147   %RHS = phi i32* [ %RHS.next, %bb ], [ %tmp, %cont ]
    148   %LHS = getelementptr inbounds i32, i32* %A.ptr, i32 100
    149   %RHS.next = getelementptr inbounds i32, i32* %RHS, i64 1
    150   %cond = icmp ult i32 * %LHS, %RHS
    151   br i1 %cond, label %bb2, label %bb
    152 
    153 bb2:
    154   ret i32* %RHS
    155 
    156 lpad:
    157   %l = landingpad { i8*, i32 } cleanup
    158   ret i32* null
    159 
    160 ; CHECK-LABEL: @test6(
    161 ; CHECK:  %[[INDEX:[0-9A-Za-z.]+]] = phi i32 [ %[[ADD:[0-9A-Za-z.]+]], %bb ], [ %Offset, %cont ]
    162 ; CHECK:  %[[ADD]] = add nsw i32 %[[INDEX]], 1
    163 ; CHECK:  %cond = icmp sgt i32 %[[INDEX]], 100
    164 ; CHECK:  br i1 %cond, label %bb2, label %bb
    165 ; CHECK:  %[[TOPTR:[0-9A-Za-z.]+]] = inttoptr i32 %[[ADD:[0-9A-Za-z.]+]] to i32*
    166 ; CHECK:  %[[PTR:[0-9A-Za-z.]+]] = getelementptr inbounds i32, i32* %[[TOPTR]], i32 %[[INDEX]]
    167 ; CHECK:  ret i32* %[[PTR]]
    168 }
    169 
    170 declare i32 @__gxx_personality_v0(...)
    171