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, 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, i32* %a, i64 %indvars.iv 20 %0 = load i32, 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, i32* %c, align 4 26 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 27 %2 = load i32, 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, 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, i32* %a, i64 %indvars.iv 59 %0 = load i32, 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, i32* %c, align 4 65 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 66 %2 = load i32, 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 an addrspacecast 82 ; CHECK-LABEL: @test2_addrspacecast 83 ; CHECK: load i32, i32 addrspace(1)* %c, align 4 84 ; CHECK: for.body: 85 86 ; Function Attrs: nounwind uwtable 87 define void @test2_addrspacecast(i32 addrspace(1)* nocapture %a, i32 addrspace(1)* nocapture readonly %b, i32 %n) #0 { 88 entry: 89 %cmp6 = icmp sgt i32 %n, 0 90 %ca = alloca i64 91 %c = addrspacecast i64* %ca to i32 addrspace(1)* 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, i32 addrspace(1)* %a, i64 %indvars.iv 97 %0 = load i32, i32 addrspace(1)* %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 %1 = load i32, i32 addrspace(1)* %c, align 4 103 %arrayidx3 = getelementptr inbounds i32, i32 addrspace(1)* %b, i64 %indvars.iv 104 %2 = load i32, i32 addrspace(1)* %arrayidx3, align 4 105 %mul = mul nsw i32 %2, %1 106 store i32 %mul, i32 addrspace(1)* %arrayidx, align 4 107 br label %for.inc 108 109 for.inc: ; preds = %for.body, %if.then 110 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 111 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 112 %exitcond = icmp eq i32 %lftr.wideiv, %n 113 br i1 %exitcond, label %for.end, label %for.body 114 115 for.end: ; preds = %for.inc, %entry 116 ret void 117 } 118 119 ; Make sure the basic alloca pointer hoisting works through a bitcast to a 120 ; pointer to a smaller type (where the bitcast also needs to be hoisted): 121 ; CHECK-LABEL: @test3 122 ; CHECK: load i32, i32* %c, align 4 123 ; CHECK: for.body: 124 125 ; Function Attrs: nounwind uwtable 126 define void @test3(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 127 entry: 128 %cmp6 = icmp sgt i32 %n, 0 129 %ca = alloca i64 130 br i1 %cmp6, label %for.body, label %for.end 131 132 for.body: ; preds = %entry, %for.inc 133 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 134 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 135 %0 = load i32, i32* %arrayidx, align 4 136 %cmp1 = icmp sgt i32 %0, 0 137 br i1 %cmp1, label %if.then, label %for.inc 138 139 if.then: ; preds = %for.body 140 %c = bitcast i64* %ca to i32* 141 %1 = load i32, i32* %c, align 4 142 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 143 %2 = load i32, i32* %arrayidx3, align 4 144 %mul = mul nsw i32 %2, %1 145 store i32 %mul, i32* %arrayidx, align 4 146 br label %for.inc 147 148 for.inc: ; preds = %for.body, %if.then 149 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 150 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 151 %exitcond = icmp eq i32 %lftr.wideiv, %n 152 br i1 %exitcond, label %for.end, label %for.body 153 154 for.end: ; preds = %for.inc, %entry 155 ret void 156 } 157 158 ; Make sure the basic alloca pointer hoisting does not happen through a bitcast 159 ; to a pointer to a larger type: 160 ; CHECK-LABEL: @test4 161 ; CHECK: for.body: 162 ; CHECK: load i32, i32* %c, align 4 163 164 ; Function Attrs: nounwind uwtable 165 define void @test4(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 166 entry: 167 %cmp6 = icmp sgt i32 %n, 0 168 %ca = alloca i16 169 %c = bitcast i16* %ca to i32* 170 br i1 %cmp6, label %for.body, label %for.end 171 172 for.body: ; preds = %entry, %for.inc 173 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 174 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 175 %0 = load i32, i32* %arrayidx, align 4 176 %cmp1 = icmp sgt i32 %0, 0 177 br i1 %cmp1, label %if.then, label %for.inc 178 179 if.then: ; preds = %for.body 180 %1 = load i32, i32* %c, align 4 181 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 182 %2 = load i32, i32* %arrayidx3, align 4 183 %mul = mul nsw i32 %2, %1 184 store i32 %mul, i32* %arrayidx, align 4 185 br label %for.inc 186 187 for.inc: ; preds = %for.body, %if.then 188 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 189 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 190 %exitcond = icmp eq i32 %lftr.wideiv, %n 191 br i1 %exitcond, label %for.end, label %for.body 192 193 for.end: ; preds = %for.inc, %entry 194 ret void 195 } 196 197 ; Don't crash on bitcasts to unsized types. 198 ; CHECK-LABEL: @test5 199 ; CHECK: for.body: 200 ; CHECK: load i32, i32* %c, align 4 201 202 %atype = type opaque 203 204 ; Function Attrs: nounwind uwtable 205 define void @test5(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 206 entry: 207 %cmp6 = icmp sgt i32 %n, 0 208 %ca = alloca i16 209 %cab = bitcast i16* %ca to %atype* 210 %c = bitcast %atype* %cab to i32* 211 br i1 %cmp6, label %for.body, label %for.end 212 213 for.body: ; preds = %entry, %for.inc 214 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 215 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 216 %0 = load i32, i32* %arrayidx, align 4 217 %cmp1 = icmp sgt i32 %0, 0 218 br i1 %cmp1, label %if.then, label %for.inc 219 220 if.then: ; preds = %for.body 221 %1 = load i32, i32* %c, align 4 222 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 223 %2 = load i32, i32* %arrayidx3, align 4 224 %mul = mul nsw i32 %2, %1 225 store i32 %mul, i32* %arrayidx, align 4 226 br label %for.inc 227 228 for.inc: ; preds = %for.body, %if.then 229 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 230 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 231 %exitcond = icmp eq i32 %lftr.wideiv, %n 232 br i1 %exitcond, label %for.end, label %for.body 233 234 for.end: ; preds = %for.inc, %entry 235 ret void 236 } 237 238 attributes #0 = { nounwind uwtable } 239 240