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 4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5 target 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 13 define void @test1(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 14 entry: 15 %cmp6 = icmp sgt i32 %n, 0 16 %c = alloca i32 17 br i1 %cmp6, label %for.body, label %for.end 18 19 for.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 26 if.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 34 for.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 40 for.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 51 define void @test2(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 52 entry: 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 58 for.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 65 if.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 73 for.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 79 for.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 89 define void @test2_addrspacecast(i32 addrspace(1)* nocapture %a, i32 addrspace(1)* nocapture readonly %b, i32 %n) #0 { 90 entry: 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 96 for.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 103 if.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 111 for.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 117 for.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 128 define void @test3(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 129 entry: 130 %cmp6 = icmp sgt i32 %n, 0 131 %ca = alloca i64 132 br i1 %cmp6, label %for.body, label %for.end 133 134 for.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 141 if.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 150 for.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 156 for.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 167 define void @test4(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 168 entry: 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 174 for.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 181 if.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 189 for.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 195 for.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 207 define void @test5(i32* nocapture %a, i32* nocapture readonly %b, i32 %n) #0 { 208 entry: 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 215 for.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 222 if.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 230 for.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 236 for.end: ; preds = %for.inc, %entry 237 ret void 238 } 239 240 attributes #0 = { nounwind uwtable } 241 242