1; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(loop-simplifycfg,licm)' -S < %s | FileCheck %s 2; RUN: opt -S -passes=licm -verify-memoryssa < %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, ptr %c, align 4 10; CHECK: for.body: 11 12; Function Attrs: nounwind uwtable 13define void @test1(ptr nocapture %a, ptr 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, ptr %a, i64 %indvars.iv 22 %0 = load i32, ptr %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, ptr %c, align 4 28 %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv 29 %2 = load i32, ptr %arrayidx3, align 4 30 %mul = mul nsw i32 %2, %1 31 store i32 %mul, ptr %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, ptr %ca, align 4 48; CHECK: for.body: 49 50; Function Attrs: nounwind uwtable 51define void @test2(ptr nocapture %a, ptr nocapture readonly %b, i32 %n) #0 { 52entry: 53 %cmp6 = icmp sgt i32 %n, 0 54 %ca = alloca i64 55 br i1 %cmp6, label %for.body, label %for.end 56 57for.body: ; preds = %entry, %for.inc 58 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 59 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv 60 %0 = load i32, ptr %arrayidx, align 4 61 %cmp1 = icmp sgt i32 %0, 0 62 br i1 %cmp1, label %if.then, label %for.inc 63 64if.then: ; preds = %for.body 65 %1 = load i32, ptr %ca, align 4 66 %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv 67 %2 = load i32, ptr %arrayidx3, align 4 68 %mul = mul nsw i32 %2, %1 69 store i32 %mul, ptr %arrayidx, align 4 70 br label %for.inc 71 72for.inc: ; preds = %for.body, %if.then 73 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 74 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 75 %exitcond = icmp eq i32 %lftr.wideiv, %n 76 br i1 %exitcond, label %for.end, label %for.body 77 78for.end: ; preds = %for.inc, %entry 79 ret void 80} 81 82; Make sure the basic alloca pointer hoisting works through an addrspacecast 83; CHECK-LABEL: @test2_addrspacecast 84; CHECK: load i32, ptr addrspace(1) %c, align 4 85; CHECK: for.body: 86 87; Function Attrs: nounwind uwtable 88define void @test2_addrspacecast(ptr addrspace(1) nocapture %a, ptr addrspace(1) nocapture readonly %b, i32 %n) #0 { 89entry: 90 %cmp6 = icmp sgt i32 %n, 0 91 %ca = alloca i64 92 %c = addrspacecast ptr %ca to ptr addrspace(1) 93 br i1 %cmp6, label %for.body, label %for.end 94 95for.body: ; preds = %entry, %for.inc 96 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 97 %arrayidx = getelementptr inbounds i32, ptr addrspace(1) %a, i64 %indvars.iv 98 %0 = load i32, ptr addrspace(1) %arrayidx, align 4 99 %cmp1 = icmp sgt i32 %0, 0 100 br i1 %cmp1, label %if.then, label %for.inc 101 102if.then: ; preds = %for.body 103 %1 = load i32, ptr addrspace(1) %c, align 4 104 %arrayidx3 = getelementptr inbounds i32, ptr addrspace(1) %b, i64 %indvars.iv 105 %2 = load i32, ptr addrspace(1) %arrayidx3, align 4 106 %mul = mul nsw i32 %2, %1 107 store i32 %mul, ptr addrspace(1) %arrayidx, align 4 108 br label %for.inc 109 110for.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 116for.end: ; preds = %for.inc, %entry 117 ret void 118} 119 120; Make sure the basic alloca pointer hoisting works through a bitcast to a 121; pointer to a smaller type (where the bitcast also needs to be hoisted): 122; CHECK-LABEL: @test3 123; CHECK: load i32, ptr %ca, align 4 124; CHECK: for.body: 125 126; Function Attrs: nounwind uwtable 127define void @test3(ptr nocapture %a, ptr nocapture readonly %b, i32 %n) #0 { 128entry: 129 %cmp6 = icmp sgt i32 %n, 0 130 %ca = alloca i64 131 br i1 %cmp6, label %for.body, label %for.end 132 133for.body: ; preds = %entry, %for.inc 134 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 135 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv 136 %0 = load i32, ptr %arrayidx, align 4 137 %cmp1 = icmp sgt i32 %0, 0 138 br i1 %cmp1, label %if.then, label %for.inc 139 140if.then: ; preds = %for.body 141 %1 = load i32, ptr %ca, align 4 142 %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv 143 %2 = load i32, ptr %arrayidx3, align 4 144 %mul = mul nsw i32 %2, %1 145 store i32 %mul, ptr %arrayidx, align 4 146 br label %for.inc 147 148for.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 154for.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, ptr %ca, align 4 163 164; Function Attrs: nounwind uwtable 165define void @test4(ptr nocapture %a, ptr nocapture readonly %b, i32 %n) #0 { 166entry: 167 %cmp6 = icmp sgt i32 %n, 0 168 %ca = alloca i16 169 br i1 %cmp6, label %for.body, label %for.end 170 171for.body: ; preds = %entry, %for.inc 172 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 173 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv 174 %0 = load i32, ptr %arrayidx, align 4 175 %cmp1 = icmp sgt i32 %0, 0 176 br i1 %cmp1, label %if.then, label %for.inc 177 178if.then: ; preds = %for.body 179 %1 = load i32, ptr %ca, align 4 180 %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv 181 %2 = load i32, ptr %arrayidx3, align 4 182 %mul = mul nsw i32 %2, %1 183 store i32 %mul, ptr %arrayidx, align 4 184 br label %for.inc 185 186for.inc: ; preds = %for.body, %if.then 187 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 188 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 189 %exitcond = icmp eq i32 %lftr.wideiv, %n 190 br i1 %exitcond, label %for.end, label %for.body 191 192for.end: ; preds = %for.inc, %entry 193 ret void 194} 195 196; Don't crash on bitcasts to unsized types. 197; CHECK-LABEL: @test5 198; CHECK: for.body: 199; CHECK: load i32, ptr %ca, align 4 200 201%atype = type opaque 202 203; Function Attrs: nounwind uwtable 204define void @test5(ptr nocapture %a, ptr nocapture readonly %b, i32 %n) #0 { 205entry: 206 %cmp6 = icmp sgt i32 %n, 0 207 %ca = alloca i16 208 br i1 %cmp6, label %for.body, label %for.end 209 210for.body: ; preds = %entry, %for.inc 211 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 212 %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv 213 %0 = load i32, ptr %arrayidx, align 4 214 %cmp1 = icmp sgt i32 %0, 0 215 br i1 %cmp1, label %if.then, label %for.inc 216 217if.then: ; preds = %for.body 218 %1 = load i32, ptr %ca, align 4 219 %arrayidx3 = getelementptr inbounds i32, ptr %b, i64 %indvars.iv 220 %2 = load i32, ptr %arrayidx3, align 4 221 %mul = mul nsw i32 %2, %1 222 store i32 %mul, ptr %arrayidx, align 4 223 br label %for.inc 224 225for.inc: ; preds = %for.body, %if.then 226 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 227 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 228 %exitcond = icmp eq i32 %lftr.wideiv, %n 229 br i1 %exitcond, label %for.end, label %for.body 230 231for.end: ; preds = %for.inc, %entry 232 ret void 233} 234 235attributes #0 = { nounwind uwtable } 236 237