1; RUN: opt -S -basicaa -licm < %s | FileCheck %s 2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 3target 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 11define void @test1(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 12entry: 13 %cmp6 = icmp sgt i32 %n, 0 14 %c = alloca i32 15 br i1 %cmp6, label %for.body, label %for.end 16 17for.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 24if.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 32for.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 38for.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 49define void @test2(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 50entry: 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 56for.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 63if.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 71for.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 77for.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 87define void @test2_addrspacecast(i32 addrspace(1)* nocapture %a, i32 addrspace(1)* nocapture readonly %b, i32 %n) #0 { 88entry: 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 94for.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 101if.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 109for.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 115for.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 126define void @test3(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 127entry: 128 %cmp6 = icmp sgt i32 %n, 0 129 %ca = alloca i64 130 br i1 %cmp6, label %for.body, label %for.end 131 132for.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 139if.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 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, i32* %c, align 4 163 164; Function Attrs: nounwind uwtable 165define void @test4(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 166entry: 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 172for.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 179if.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 187for.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 193for.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 205define void @test5(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 206entry: 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 213for.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 220if.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 228for.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 234for.end: ; preds = %for.inc, %entry 235 ret void 236} 237 238attributes #0 = { nounwind uwtable } 239 240