1; RUN: opt -S -basicaa -licm < %s | FileCheck %s 2; RUN: opt -aa-pipeline=basic-aa -passes='loop-simplify,require<aa>,require<targetir>,require<scalar-evolution>,loop(simplify-cfg,licm)' -S < %s | FileCheck %s 3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4target triple = "x86_64-unknown-linux-gnu" 5 6; Make sure the basic alloca pointer hoisting works: 7; CHECK-LABEL: @test1 8; CHECK: load i32, i32* %c, align 4 9; CHECK: for.body: 10 11; Function Attrs: nounwind uwtable 12define void @test1(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 13entry: 14 %cmp6 = icmp sgt i32 %n, 0 15 %c = alloca i32 16 br i1 %cmp6, label %for.body, label %for.end 17 18for.body: ; preds = %entry, %for.inc 19 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 20 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 21 %0 = load i32, i32* %arrayidx, align 4 22 %cmp1 = icmp sgt i32 %0, 0 23 br i1 %cmp1, label %if.then, label %for.inc 24 25if.then: ; preds = %for.body 26 %1 = load i32, i32* %c, align 4 27 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 28 %2 = load i32, i32* %arrayidx3, align 4 29 %mul = mul nsw i32 %2, %1 30 store i32 %mul, i32* %arrayidx, align 4 31 br label %for.inc 32 33for.inc: ; preds = %for.body, %if.then 34 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 35 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 36 %exitcond = icmp eq i32 %lftr.wideiv, %n 37 br i1 %exitcond, label %for.end, label %for.body 38 39for.end: ; preds = %for.inc, %entry 40 ret void 41} 42 43; Make sure the basic alloca pointer hoisting works through a bitcast to a 44; pointer to a smaller type: 45; CHECK-LABEL: @test2 46; CHECK: load i32, i32* %c, align 4 47; CHECK: for.body: 48 49; Function Attrs: nounwind uwtable 50define void @test2(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 51entry: 52 %cmp6 = icmp sgt i32 %n, 0 53 %ca = alloca i64 54 %c = bitcast i64* %ca to i32* 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, i32* %a, i64 %indvars.iv 60 %0 = load i32, i32* %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, i32* %c, align 4 66 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 67 %2 = load i32, i32* %arrayidx3, align 4 68 %mul = mul nsw i32 %2, %1 69 store i32 %mul, i32* %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, i32 addrspace(1)* %c, align 4 85; CHECK: for.body: 86 87; Function Attrs: nounwind uwtable 88define void @test2_addrspacecast(i32 addrspace(1)* nocapture %a, i32 addrspace(1)* nocapture readonly %b, i32 %n) #0 { 89entry: 90 %cmp6 = icmp sgt i32 %n, 0 91 %ca = alloca i64 92 %c = addrspacecast i64* %ca to i32 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, i32 addrspace(1)* %a, i64 %indvars.iv 98 %0 = load i32, i32 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, i32 addrspace(1)* %c, align 4 104 %arrayidx3 = getelementptr inbounds i32, i32 addrspace(1)* %b, i64 %indvars.iv 105 %2 = load i32, i32 addrspace(1)* %arrayidx3, align 4 106 %mul = mul nsw i32 %2, %1 107 store i32 %mul, i32 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, i32* %c, align 4 124; CHECK: for.body: 125 126; Function Attrs: nounwind uwtable 127define void @test3(i32* nocapture %a, i32* 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, i32* %a, i64 %indvars.iv 136 %0 = load i32, i32* %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 %c = bitcast i64* %ca to i32* 142 %1 = load i32, i32* %c, align 4 143 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 144 %2 = load i32, 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 149for.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 155for.end: ; preds = %for.inc, %entry 156 ret void 157} 158 159; Make sure the basic alloca pointer hoisting does not happen through a bitcast 160; to a pointer to a larger type: 161; CHECK-LABEL: @test4 162; CHECK: for.body: 163; CHECK: load i32, i32* %c, align 4 164 165; Function Attrs: nounwind uwtable 166define void @test4(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 167entry: 168 %cmp6 = icmp sgt i32 %n, 0 169 %ca = alloca i16 170 %c = bitcast i16* %ca to i32* 171 br i1 %cmp6, label %for.body, label %for.end 172 173for.body: ; preds = %entry, %for.inc 174 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 175 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 176 %0 = load i32, i32* %arrayidx, align 4 177 %cmp1 = icmp sgt i32 %0, 0 178 br i1 %cmp1, label %if.then, label %for.inc 179 180if.then: ; preds = %for.body 181 %1 = load i32, i32* %c, align 4 182 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 183 %2 = load i32, i32* %arrayidx3, align 4 184 %mul = mul nsw i32 %2, %1 185 store i32 %mul, i32* %arrayidx, align 4 186 br label %for.inc 187 188for.inc: ; preds = %for.body, %if.then 189 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 190 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 191 %exitcond = icmp eq i32 %lftr.wideiv, %n 192 br i1 %exitcond, label %for.end, label %for.body 193 194for.end: ; preds = %for.inc, %entry 195 ret void 196} 197 198; Don't crash on bitcasts to unsized types. 199; CHECK-LABEL: @test5 200; CHECK: for.body: 201; CHECK: load i32, i32* %c, align 4 202 203%atype = type opaque 204 205; Function Attrs: nounwind uwtable 206define void @test5(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 207entry: 208 %cmp6 = icmp sgt i32 %n, 0 209 %ca = alloca i16 210 %cab = bitcast i16* %ca to %atype* 211 %c = bitcast %atype* %cab to i32* 212 br i1 %cmp6, label %for.body, label %for.end 213 214for.body: ; preds = %entry, %for.inc 215 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] 216 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 217 %0 = load i32, i32* %arrayidx, align 4 218 %cmp1 = icmp sgt i32 %0, 0 219 br i1 %cmp1, label %if.then, label %for.inc 220 221if.then: ; preds = %for.body 222 %1 = load i32, i32* %c, align 4 223 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv 224 %2 = load i32, i32* %arrayidx3, align 4 225 %mul = mul nsw i32 %2, %1 226 store i32 %mul, i32* %arrayidx, align 4 227 br label %for.inc 228 229for.inc: ; preds = %for.body, %if.then 230 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 231 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 232 %exitcond = icmp eq i32 %lftr.wideiv, %n 233 br i1 %exitcond, label %for.end, label %for.body 234 235for.end: ; preds = %for.inc, %entry 236 ret void 237} 238 239attributes #0 = { nounwind uwtable } 240 241