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