Home | History | Annotate | Download | only in LICM
      1 ; REQUIRES: aarch64-registered-target
      2 
      3 ; RUN: opt < %s  -licm -S   | FileCheck %s
      4 
      5 target triple = "aarch64--linux-gnueabi"
      6 
      7 ; CHECK-LABEL:@test1
      8 ; CHECK-LABEL:loopexit1:
      9 ; CHECK: %[[PHI:.+]] = phi i8** [ %arrayidx0, %if.end ]
     10 ; CHECK: getelementptr inbounds i8*, i8** %[[PHI]], i64 1
     11 define i8** @test1(i32 %j, i8** readonly %P, i8* readnone %Q) {
     12 entry:
     13   %cmp0 = icmp slt i32 0, %j
     14   br i1 %cmp0, label %for.body.lr.ph, label %return
     15 
     16 for.body.lr.ph:
     17   br label %for.body
     18 
     19 for.body:
     20   %P.addr = phi i8** [ %P, %for.body.lr.ph ], [ %arrayidx0, %if.end  ]
     21   %i0 = phi i32 [ 0, %for.body.lr.ph ], [ %i.add, %if.end]
     22 
     23   %i0.ext = sext i32 %i0 to i64
     24   %arrayidx0 = getelementptr inbounds i8*, i8** %P.addr, i64 %i0.ext
     25   %l0 = load i8*, i8** %arrayidx0, align 8
     26   %cmp1 = icmp ugt i8* %l0, %Q
     27   br i1 %cmp1, label %loopexit0, label %if.end
     28 
     29 if.end:                                           ; preds = %for.body
     30   %arrayidx1 = getelementptr inbounds i8*, i8** %arrayidx0, i64 1
     31   %l1 = load i8*, i8** %arrayidx1, align 8
     32   %cmp4 = icmp ugt i8* %l1, %Q
     33   %i.add = add nsw i32 %i0, 2
     34   br i1 %cmp4, label %loopexit1, label %for.body
     35 
     36 loopexit0:
     37   %p1 = phi i8** [%arrayidx0, %for.body]
     38   br label %return
     39 
     40 loopexit1:
     41   %p2 = phi i8** [%arrayidx1, %if.end]
     42   br label  %return
     43 
     44 return:
     45   %retval.0 = phi i8** [ %p1, %loopexit0 ], [%p2, %loopexit1], [ null, %entry ]
     46   ret i8** %retval.0
     47 }
     48 
     49 ; CHECK-LABEL: @test2
     50 ; CHECK-LABEL: loopexit2:
     51 ; CHECK: %[[PHI:.*]] = phi i8** [ %add.ptr, %if.end ]
     52 ; CHECK: getelementptr inbounds i8*, i8** %[[PHI]]
     53 define i8** @test2(i32 %j, i8** readonly %P, i8* readnone %Q) {
     54 
     55 entry:
     56   br label %for.body
     57 
     58 for.cond:
     59   %i.addr.0 = phi i32 [ %add, %if.end ]
     60   %P.addr.0 = phi i8** [ %add.ptr, %if.end ]
     61   %cmp = icmp slt i32 %i.addr.0, %j
     62   br i1 %cmp, label %for.body, label %loopexit0
     63 
     64 for.body:
     65   %P.addr = phi i8** [ %P, %entry ], [ %P.addr.0, %for.cond ]
     66   %i.addr = phi i32 [ 0, %entry ], [ %i.addr.0, %for.cond ]
     67 
     68   %idx.ext = sext i32 %i.addr to i64
     69   %add.ptr = getelementptr inbounds i8*, i8** %P.addr, i64 %idx.ext
     70   %l0 = load i8*, i8** %add.ptr, align 8
     71 
     72   %cmp1 = icmp ugt i8* %l0, %Q
     73   br i1 %cmp1, label %loopexit1, label %if.end
     74 
     75 if.end:
     76   %add.i = add i32 %i.addr, 1
     77   %idx2.ext = sext i32 %add.i to i64
     78   %arrayidx2 = getelementptr inbounds i8*, i8** %add.ptr, i64 %idx2.ext
     79   %l1 = load i8*, i8** %arrayidx2, align 8
     80   %cmp2 = icmp ugt i8* %l1, %Q
     81   %add = add nsw i32 %add.i, 1
     82   br i1 %cmp2, label %loopexit2, label %for.cond
     83 
     84 loopexit0:
     85   %p0 = phi i8** [ null, %for.cond ]
     86   br label %return
     87 
     88 loopexit1:
     89   %p1 = phi i8** [ %add.ptr, %for.body ]
     90   br label %return
     91 
     92 loopexit2:
     93   %p2 = phi i8** [ %arrayidx2, %if.end ]
     94   br label %return
     95 
     96 return:
     97   %retval.0 = phi i8** [ %p1, %loopexit1 ], [ %p2, %loopexit2 ], [ %p0, %loopexit0 ]
     98   ret i8** %retval.0
     99 }
    100 
    101 
    102 ; CHECK-LABEL: @test3
    103 ; CHECK-LABEL: loopexit1:
    104 ; CHECK: %[[ADD:.*]]  = phi i64 [ %add, %if.end ]
    105 ; CHECK: %[[ADDR:.*]] = phi i8** [ %P.addr, %if.end ]
    106 ; CHECK: %[[TRUNC:.*]] = trunc i64 %[[ADD]] to i32
    107 ; CHECK: getelementptr inbounds i8*, i8** %[[ADDR]], i32 %[[TRUNC]]
    108 ; CHECK: call void @dummy(i32 %[[TRUNC]])
    109 define i8** @test3(i64 %j, i8** readonly %P, i8* readnone %Q) {
    110 entry:
    111   %cmp0 = icmp slt i64 0, %j
    112   br i1 %cmp0, label %for.body.lr.ph, label %return
    113 
    114 for.body.lr.ph:
    115   br label %for.body
    116 
    117 for.body:
    118   %P.addr = phi i8** [ %P, %for.body.lr.ph ], [ %arrayidx0, %if.end  ]
    119   %i0 = phi i32 [ 0, %for.body.lr.ph ], [ %i.add, %if.end]
    120 
    121   %i0.ext = sext i32 %i0 to i64
    122   %arrayidx0 = getelementptr inbounds i8*, i8** %P.addr, i64 %i0.ext
    123   %l0 = load i8*, i8** %arrayidx0, align 8
    124   %cmp1 = icmp ugt i8* %l0, %Q
    125   br i1 %cmp1, label %loopexit0, label %if.end
    126 
    127 if.end:                                           ; preds = %for.body
    128   %add = add i64 %i0.ext, 1
    129   %trunc = trunc i64 %add to i32
    130   %arrayidx1 = getelementptr inbounds i8*, i8** %P.addr, i32 %trunc
    131   %l1 = load i8*, i8** %arrayidx1, align 8
    132   %cmp4 = icmp ugt i8* %l1, %Q
    133   %i.add = add nsw i32 %i0, 2
    134   br i1 %cmp4, label %loopexit1, label %for.body
    135 
    136 loopexit0:
    137   %p1 = phi i8** [%arrayidx0, %for.body]
    138   br label %return
    139 
    140 loopexit1:
    141   %p2 = phi i8** [%arrayidx1, %if.end]
    142   call void @dummy(i32 %trunc)
    143   br label  %return
    144 
    145 return:
    146   %retval.0 = phi i8** [ %p1, %loopexit0 ], [%p2, %loopexit1], [ null, %entry ]
    147   ret i8** %retval.0
    148 }
    149 
    150 declare void @dummy(i32)
    151