1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define void @test1(ptr %a, ptr readnone %a_end, ptr %b.i64) { 5; CHECK-LABEL: @test1( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[CMP1:%.*]] = icmp ult ptr [[A:%.*]], [[A_END:%.*]] 8; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]] 9; CHECK: for.body.preheader: 10; CHECK-NEXT: [[B:%.*]] = load i64, ptr [[B_I64:%.*]], align 8 11; CHECK-NEXT: [[B_PTR:%.*]] = inttoptr i64 [[B]] to ptr 12; CHECK-NEXT: br label [[FOR_BODY:%.*]] 13; CHECK: for.body: 14; CHECK-NEXT: [[A_ADDR_03:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[A]], [[FOR_BODY_PREHEADER]] ] 15; CHECK-NEXT: [[B_ADDR_02_PTR:%.*]] = phi ptr [ [[ADD:%.*]], [[FOR_BODY]] ], [ [[B_PTR]], [[FOR_BODY_PREHEADER]] ] 16; CHECK-NEXT: [[I1:%.*]] = load float, ptr [[B_ADDR_02_PTR]], align 4 17; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[I1]], 4.200000e+01 18; CHECK-NEXT: store float [[MUL_I]], ptr [[A_ADDR_03]], align 4 19; CHECK-NEXT: [[ADD]] = getelementptr inbounds nuw i8, ptr [[B_ADDR_02_PTR]], i64 4 20; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[A_ADDR_03]], i64 4 21; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[INCDEC_PTR]], [[A_END]] 22; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] 23; CHECK: for.end: 24; CHECK-NEXT: ret void 25; 26entry: 27 %cmp1 = icmp ult ptr %a, %a_end 28 br i1 %cmp1, label %for.body.preheader, label %for.end 29 30for.body.preheader: ; preds = %entry 31 %b = load i64, ptr %b.i64, align 8 32 br label %for.body 33 34for.body: ; preds = %for.body, %for.body.preheader 35 %a.addr.03 = phi ptr [ %incdec.ptr, %for.body ], [ %a, %for.body.preheader ] 36 %b.addr.02 = phi i64 [ %add.int, %for.body ], [ %b, %for.body.preheader ] 37 38 39 %tmp = inttoptr i64 %b.addr.02 to ptr 40 %i1 = load float, ptr %tmp, align 4 41 %mul.i = fmul float %i1, 4.200000e+01 42 store float %mul.i, ptr %a.addr.03, align 4 43 %add = getelementptr inbounds float, ptr %tmp, i64 1 44 %add.int = ptrtoint ptr %add to i64 45 %incdec.ptr = getelementptr inbounds float, ptr %a.addr.03, i64 1 46 %cmp = icmp ult ptr %incdec.ptr, %a_end 47 br i1 %cmp, label %for.body, label %for.end 48 49for.end: ; preds = %for.body, %entry 50 ret void 51} 52 53define void @test1_neg(ptr %a, ptr readnone %a_end, ptr %b.i64) { 54; CHECK-LABEL: @test1_neg( 55; CHECK-NEXT: entry: 56; CHECK-NEXT: [[CMP1:%.*]] = icmp ult ptr [[A:%.*]], [[A_END:%.*]] 57; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]] 58; CHECK: for.body.preheader: 59; CHECK-NEXT: [[B:%.*]] = load i64, ptr [[B_I64:%.*]], align 8 60; CHECK-NEXT: [[TMP0:%.*]] = inttoptr i64 [[B]] to ptr 61; CHECK-NEXT: br label [[FOR_BODY:%.*]] 62; CHECK: for.body: 63; CHECK-NEXT: [[A_ADDR_03:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[BB:%.*]] ], [ [[A]], [[FOR_BODY_PREHEADER]] ] 64; CHECK-NEXT: [[B_ADDR_02:%.*]] = phi ptr [ [[ADD:%.*]], [[BB]] ], [ [[TMP0]], [[FOR_BODY_PREHEADER]] ] 65; CHECK-NEXT: [[PTRCMP:%.*]] = icmp ult ptr [[B_ADDR_02]], [[A_END]] 66; CHECK-NEXT: br i1 [[PTRCMP]], label [[FOR_END]], label [[BB]] 67; CHECK: bb: 68; CHECK-NEXT: [[I1:%.*]] = load float, ptr [[A]], align 4 69; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[I1]], 4.200000e+01 70; CHECK-NEXT: store float [[MUL_I]], ptr [[A_ADDR_03]], align 4 71; CHECK-NEXT: [[ADD]] = getelementptr inbounds nuw i8, ptr [[A]], i64 4 72; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[A_ADDR_03]], i64 4 73; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[INCDEC_PTR]], [[A_END]] 74; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] 75; CHECK: for.end: 76; CHECK-NEXT: ret void 77; 78entry: 79 %cmp1 = icmp ult ptr %a, %a_end 80 br i1 %cmp1, label %for.body.preheader, label %for.end 81 82for.body.preheader: ; preds = %entry 83 %b = load i64, ptr %b.i64, align 8 84 br label %for.body 85 86for.body: ; preds = %for.body, %for.body.preheader 87 %a.addr.03 = phi ptr [ %incdec.ptr, %bb ], [ %a, %for.body.preheader ] 88 %b.addr.02 = phi i64 [ %add.int, %bb ], [ %b, %for.body.preheader ] 89 90 91 %tmp = inttoptr i64 %b.addr.02 to ptr 92 %ptrcmp = icmp ult ptr %tmp, %a_end 93 br i1 %ptrcmp, label %for.end, label %bb 94 95bb: 96 %i1 = load float, ptr %a, align 4 97 %mul.i = fmul float %i1, 4.200000e+01 98 store float %mul.i, ptr %a.addr.03, align 4 99 %add = getelementptr inbounds float, ptr %a, i64 1 100 %add.int = ptrtoint ptr %add to i64 101 %incdec.ptr = getelementptr inbounds float, ptr %a.addr.03, i64 1 102 %cmp = icmp ult ptr %incdec.ptr, %a_end 103 br i1 %cmp, label %for.body, label %for.end 104 105for.end: ; preds = %for.body, %entry 106 ret void 107} 108 109 110define void @test2(ptr %a, ptr readnone %a_end, ptr %b.float) { 111; CHECK-LABEL: @test2( 112; CHECK-NEXT: entry: 113; CHECK-NEXT: [[CMP1:%.*]] = icmp ult ptr [[A:%.*]], [[A_END:%.*]] 114; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]] 115; CHECK: for.body.preheader: 116; CHECK-NEXT: [[B:%.*]] = load i64, ptr [[B_FLOAT:%.*]], align 8 117; CHECK-NEXT: [[B_PTR:%.*]] = inttoptr i64 [[B]] to ptr 118; CHECK-NEXT: br label [[FOR_BODY:%.*]] 119; CHECK: for.body: 120; CHECK-NEXT: [[A_ADDR_03:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[A]], [[FOR_BODY_PREHEADER]] ] 121; CHECK-NEXT: [[B_ADDR_02_PTR:%.*]] = phi ptr [ [[ADD:%.*]], [[FOR_BODY]] ], [ [[B_PTR]], [[FOR_BODY_PREHEADER]] ] 122; CHECK-NEXT: [[I1:%.*]] = load float, ptr [[B_ADDR_02_PTR]], align 4 123; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[I1]], 4.200000e+01 124; CHECK-NEXT: store float [[MUL_I]], ptr [[A_ADDR_03]], align 4 125; CHECK-NEXT: [[ADD]] = getelementptr inbounds nuw i8, ptr [[B_ADDR_02_PTR]], i64 4 126; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[A_ADDR_03]], i64 4 127; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[INCDEC_PTR]], [[A_END]] 128; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] 129; CHECK: for.end: 130; CHECK-NEXT: ret void 131; 132entry: 133 %cmp1 = icmp ult ptr %a, %a_end 134 br i1 %cmp1, label %for.body.preheader, label %for.end 135 136for.body.preheader: ; preds = %entry 137 %b = load i64, ptr %b.float, align 8 138 br label %for.body 139 140for.body: ; preds = %for.body, %for.body.preheader 141 %a.addr.03 = phi ptr [ %incdec.ptr, %for.body ], [ %a, %for.body.preheader ] 142 %b.addr.02 = phi i64 [ %add.int, %for.body ], [ %b, %for.body.preheader ] 143 144 145 %tmp = inttoptr i64 %b.addr.02 to ptr 146 %i1 = load float, ptr %tmp, align 4 147 %mul.i = fmul float %i1, 4.200000e+01 148 store float %mul.i, ptr %a.addr.03, align 4 149 %add = getelementptr inbounds float, ptr %tmp, i64 1 150 %add.int = ptrtoint ptr %add to i64 151 %incdec.ptr = getelementptr inbounds float, ptr %a.addr.03, i64 1 152 %cmp = icmp ult ptr %incdec.ptr, %a_end 153 br i1 %cmp, label %for.body, label %for.end 154 155for.end: ; preds = %for.body, %entry 156 ret void 157} 158 159 160define void @test3(ptr %a, ptr readnone %a_end, ptr %b.i8p) { 161; CHECK-LABEL: @test3( 162; CHECK-NEXT: entry: 163; CHECK-NEXT: [[CMP1:%.*]] = icmp ult ptr [[A:%.*]], [[A_END:%.*]] 164; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]] 165; CHECK: for.body.preheader: 166; CHECK-NEXT: [[B:%.*]] = load i64, ptr [[B_I8P:%.*]], align 8 167; CHECK-NEXT: [[B_PTR:%.*]] = inttoptr i64 [[B]] to ptr 168; CHECK-NEXT: br label [[FOR_BODY:%.*]] 169; CHECK: for.body: 170; CHECK-NEXT: [[A_ADDR_03:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[A]], [[FOR_BODY_PREHEADER]] ] 171; CHECK-NEXT: [[B_ADDR_02_PTR:%.*]] = phi ptr [ [[ADD:%.*]], [[FOR_BODY]] ], [ [[B_PTR]], [[FOR_BODY_PREHEADER]] ] 172; CHECK-NEXT: [[I1:%.*]] = load float, ptr [[B_ADDR_02_PTR]], align 4 173; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[I1]], 4.200000e+01 174; CHECK-NEXT: store float [[MUL_I]], ptr [[A_ADDR_03]], align 4 175; CHECK-NEXT: [[ADD]] = getelementptr inbounds nuw i8, ptr [[B_ADDR_02_PTR]], i64 4 176; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[A_ADDR_03]], i64 4 177; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[INCDEC_PTR]], [[A_END]] 178; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] 179; CHECK: for.end: 180; CHECK-NEXT: ret void 181; 182entry: 183 %cmp1 = icmp ult ptr %a, %a_end 184 br i1 %cmp1, label %for.body.preheader, label %for.end 185 186for.body.preheader: ; preds = %entry 187 %b = load i64, ptr %b.i8p, align 8 188 br label %for.body 189 190for.body: ; preds = %for.body, %for.body.preheader 191 %a.addr.03 = phi ptr [ %incdec.ptr, %for.body ], [ %a, %for.body.preheader ] 192 %b.addr.02 = phi i64 [ %add.int, %for.body ], [ %b, %for.body.preheader ] 193 194 195 %tmp = inttoptr i64 %b.addr.02 to ptr 196 %i1 = load float, ptr %tmp, align 4 197 %mul.i = fmul float %i1, 4.200000e+01 198 store float %mul.i, ptr %a.addr.03, align 4 199 %add = getelementptr inbounds float, ptr %tmp, i64 1 200 %add.int = ptrtoint ptr %add to i64 201 %incdec.ptr = getelementptr inbounds float, ptr %a.addr.03, i64 1 202 %cmp = icmp ult ptr %incdec.ptr, %a_end 203 br i1 %cmp, label %for.body, label %for.end 204 205for.end: ; preds = %for.body, %entry 206 ret void 207} 208 209 210define void @test4(ptr %a, ptr readnone %a_end, ptr %b.float) { 211; CHECK-LABEL: @test4( 212; CHECK-NEXT: entry: 213; CHECK-NEXT: [[CMP1:%.*]] = icmp ult ptr [[A:%.*]], [[A_END:%.*]] 214; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]] 215; CHECK: for.body.preheader: 216; CHECK-NEXT: [[B_F:%.*]] = load ptr, ptr [[B_FLOAT:%.*]], align 8 217; CHECK-NEXT: br label [[FOR_BODY:%.*]] 218; CHECK: for.body: 219; CHECK-NEXT: [[A_ADDR_03:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[FOR_BODY]] ], [ [[A]], [[FOR_BODY_PREHEADER]] ] 220; CHECK-NEXT: [[B_ADDR_02_IN:%.*]] = phi ptr [ [[ADD:%.*]], [[FOR_BODY]] ], [ [[B_F]], [[FOR_BODY_PREHEADER]] ] 221; CHECK-NEXT: [[I1:%.*]] = load float, ptr [[B_ADDR_02_IN]], align 4 222; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[I1]], 4.200000e+01 223; CHECK-NEXT: store float [[MUL_I]], ptr [[A_ADDR_03]], align 4 224; CHECK-NEXT: [[ADD]] = getelementptr inbounds nuw i8, ptr [[B_ADDR_02_IN]], i64 4 225; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[A_ADDR_03]], i64 4 226; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[INCDEC_PTR]], [[A_END]] 227; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]] 228; CHECK: for.end: 229; CHECK-NEXT: ret void 230; 231entry: 232 %cmp1 = icmp ult ptr %a, %a_end 233 br i1 %cmp1, label %for.body.preheader, label %for.end 234 235for.body.preheader: ; preds = %entry 236 %b.f = load ptr, ptr %b.float, align 8 237 %b = ptrtoint ptr %b.f to i64 238 br label %for.body 239 240for.body: ; preds = %for.body, %for.body.preheader 241 %a.addr.03 = phi ptr [ %incdec.ptr, %for.body ], [ %a, %for.body.preheader ] 242 %b.addr.02 = phi i64 [ %add.int, %for.body ], [ %b, %for.body.preheader ] 243 %tmp = inttoptr i64 %b.addr.02 to ptr 244 %i1 = load float, ptr %tmp, align 4 245 %mul.i = fmul float %i1, 4.200000e+01 246 store float %mul.i, ptr %a.addr.03, align 4 247 %add = getelementptr inbounds float, ptr %tmp, i64 1 248 %add.int = ptrtoint ptr %add to i64 249 %incdec.ptr = getelementptr inbounds float, ptr %a.addr.03, i64 1 250 %cmp = icmp ult ptr %incdec.ptr, %a_end 251 br i1 %cmp, label %for.body, label %for.end 252 253for.end: ; preds = %for.body, %entry 254 ret void 255} 256