1 ; RUN: opt -S -basicaa -licm < %s | FileCheck %s 2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3 target triple = "x86_64-unknown-linux-gnu" 4 5 ; Make sure the basic alloca pointer hoisting works: 6 ; CHECK-LABEL: @test1 7 ; CHECK: load i32* %c, align 4 8 ; CHECK: for.body: 9 10 ; Function Attrs: nounwind uwtable 11 define void @test1(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 12 entry: 13 %cmp6 = icmp sgt i32 %n, 0 14 %c = alloca i32 15 br i1 %cmp6, label %for.body, label %for.end 16 17 for.body: ; preds = %entry, %for.inc 18 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 19 %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv 20 %0 = load i32* %arrayidx, align 4 21 %cmp1 = icmp sgt i32 %0, 0 22 br i1 %cmp1, label %if.then, label %for.inc 23 24 if.then: ; preds = %for.body 25 %1 = load i32* %c, align 4 26 %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv 27 %2 = load i32* %arrayidx3, align 4 28 %mul = mul nsw i32 %2, %1 29 store i32 %mul, i32* %arrayidx, align 4 30 br label %for.inc 31 32 for.inc: ; preds = %for.body, %if.then 33 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 34 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 35 %exitcond = icmp eq i32 %lftr.wideiv, %n 36 br i1 %exitcond, label %for.end, label %for.body 37 38 for.end: ; preds = %for.inc, %entry 39 ret void 40 } 41 42 ; Make sure the basic alloca pointer hoisting works through a bitcast to a 43 ; pointer to a smaller type: 44 ; CHECK-LABEL: @test2 45 ; CHECK: load i32* %c, align 4 46 ; CHECK: for.body: 47 48 ; Function Attrs: nounwind uwtable 49 define void @test2(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 50 entry: 51 %cmp6 = icmp sgt i32 %n, 0 52 %ca = alloca i64 53 %c = bitcast i64* %ca to i32* 54 br i1 %cmp6, label %for.body, label %for.end 55 56 for.body: ; preds = %entry, %for.inc 57 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 58 %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv 59 %0 = load i32* %arrayidx, align 4 60 %cmp1 = icmp sgt i32 %0, 0 61 br i1 %cmp1, label %if.then, label %for.inc 62 63 if.then: ; preds = %for.body 64 %1 = load i32* %c, align 4 65 %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv 66 %2 = load i32* %arrayidx3, align 4 67 %mul = mul nsw i32 %2, %1 68 store i32 %mul, i32* %arrayidx, align 4 69 br label %for.inc 70 71 for.inc: ; preds = %for.body, %if.then 72 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 73 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 74 %exitcond = icmp eq i32 %lftr.wideiv, %n 75 br i1 %exitcond, label %for.end, label %for.body 76 77 for.end: ; preds = %for.inc, %entry 78 ret void 79 } 80 81 ; Make sure the basic alloca pointer hoisting works through a bitcast to a 82 ; pointer to a smaller type (where the bitcast also needs to be hoisted): 83 ; CHECK-LABEL: @test3 84 ; CHECK: load i32* %c, align 4 85 ; CHECK: for.body: 86 87 ; Function Attrs: nounwind uwtable 88 define void @test3(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 89 entry: 90 %cmp6 = icmp sgt i32 %n, 0 91 %ca = alloca i64 92 br i1 %cmp6, label %for.body, label %for.end 93 94 for.body: ; preds = %entry, %for.inc 95 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 96 %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv 97 %0 = load i32* %arrayidx, align 4 98 %cmp1 = icmp sgt i32 %0, 0 99 br i1 %cmp1, label %if.then, label %for.inc 100 101 if.then: ; preds = %for.body 102 %c = bitcast i64* %ca to i32* 103 %1 = load i32* %c, align 4 104 %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv 105 %2 = load i32* %arrayidx3, align 4 106 %mul = mul nsw i32 %2, %1 107 store i32 %mul, i32* %arrayidx, align 4 108 br label %for.inc 109 110 for.inc: ; preds = %for.body, %if.then 111 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 112 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 113 %exitcond = icmp eq i32 %lftr.wideiv, %n 114 br i1 %exitcond, label %for.end, label %for.body 115 116 for.end: ; preds = %for.inc, %entry 117 ret void 118 } 119 120 ; Make sure the basic alloca pointer hoisting does not happen through a bitcast 121 ; to a pointer to a larger type: 122 ; CHECK-LABEL: @test4 123 ; CHECK: for.body: 124 ; CHECK: load i32* %c, align 4 125 126 ; Function Attrs: nounwind uwtable 127 define void @test4(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 128 entry: 129 %cmp6 = icmp sgt i32 %n, 0 130 %ca = alloca i16 131 %c = bitcast i16* %ca to i32* 132 br i1 %cmp6, label %for.body, label %for.end 133 134 for.body: ; preds = %entry, %for.inc 135 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 136 %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv 137 %0 = load i32* %arrayidx, align 4 138 %cmp1 = icmp sgt i32 %0, 0 139 br i1 %cmp1, label %if.then, label %for.inc 140 141 if.then: ; preds = %for.body 142 %1 = load i32* %c, align 4 143 %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv 144 %2 = load i32* %arrayidx3, align 4 145 %mul = mul nsw i32 %2, %1 146 store i32 %mul, i32* %arrayidx, align 4 147 br label %for.inc 148 149 for.inc: ; preds = %for.body, %if.then 150 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 151 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 152 %exitcond = icmp eq i32 %lftr.wideiv, %n 153 br i1 %exitcond, label %for.end, label %for.body 154 155 for.end: ; preds = %for.inc, %entry 156 ret void 157 } 158 159 ; Don't crash on bitcasts to unsized types. 160 ; CHECK-LABEL: @test5 161 ; CHECK: for.body: 162 ; CHECK: load i32* %c, align 4 163 164 %atype = type opaque 165 166 ; Function Attrs: nounwind uwtable 167 define void @test5(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 168 entry: 169 %cmp6 = icmp sgt i32 %n, 0 170 %ca = alloca i16 171 %cab = bitcast i16* %ca to %atype* 172 %c = bitcast %atype* %cab to i32* 173 br i1 %cmp6, label %for.body, label %for.end 174 175 for.body: ; preds = %entry, %for.inc 176 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 177 %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv 178 %0 = load i32* %arrayidx, align 4 179 %cmp1 = icmp sgt i32 %0, 0 180 br i1 %cmp1, label %if.then, label %for.inc 181 182 if.then: ; preds = %for.body 183 %1 = load i32* %c, align 4 184 %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv 185 %2 = load i32* %arrayidx3, align 4 186 %mul = mul nsw i32 %2, %1 187 store i32 %mul, i32* %arrayidx, align 4 188 br label %for.inc 189 190 for.inc: ; preds = %for.body, %if.then 191 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 192 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 193 %exitcond = icmp eq i32 %lftr.wideiv, %n 194 br i1 %exitcond, label %for.end, label %for.body 195 196 for.end: ; preds = %for.inc, %entry 197 ret void 198 } 199 200 attributes #0 = { nounwind uwtable } 201 202