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