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