280 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=slp-vectorizer -mtriple=aarch64 < %s | FileCheck %s3 4target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"5 6define void @ldexp_f32i32(ptr %x, ptr %y, i32 %exp) {7; CHECK-LABEL: @ldexp_f32i32(8; CHECK-NEXT: entry:9; CHECK-NEXT: [[L0:%.*]] = load float, ptr [[X:%.*]], align 410; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds float, ptr [[X]], i64 111; CHECK-NEXT: [[L2:%.*]] = load float, ptr [[ARRAYIDX_1]], align 412; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds float, ptr [[X]], i64 213; CHECK-NEXT: [[L4:%.*]] = load float, ptr [[ARRAYIDX_2]], align 414; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds float, ptr [[X]], i64 315; CHECK-NEXT: [[L6:%.*]] = load float, ptr [[ARRAYIDX_3]], align 416; CHECK-NEXT: [[L1:%.*]] = tail call float @llvm.ldexp.f32.i32(float [[L0]], i32 [[EXP:%.*]])17; CHECK-NEXT: [[L3:%.*]] = tail call float @llvm.ldexp.f32.i32(float [[L2]], i32 [[EXP]])18; CHECK-NEXT: [[L5:%.*]] = tail call float @llvm.ldexp.f32.i32(float [[L4]], i32 [[EXP]])19; CHECK-NEXT: [[L7:%.*]] = tail call float @llvm.ldexp.f32.i32(float [[L6]], i32 [[EXP]])20; CHECK-NEXT: store float [[L1]], ptr [[Y:%.*]], align 421; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds float, ptr [[Y]], i64 122; CHECK-NEXT: store float [[L3]], ptr [[ARRAYIDX2_1]], align 423; CHECK-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds float, ptr [[Y]], i64 224; CHECK-NEXT: store float [[L5]], ptr [[ARRAYIDX2_2]], align 425; CHECK-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds float, ptr [[Y]], i64 326; CHECK-NEXT: store float [[L7]], ptr [[ARRAYIDX2_3]], align 427; CHECK-NEXT: ret void28;29entry:30 %l0 = load float, ptr %x, align 431 %arrayidx.1 = getelementptr inbounds float, ptr %x, i64 132 %l2 = load float, ptr %arrayidx.1, align 433 %arrayidx.2 = getelementptr inbounds float, ptr %x, i64 234 %l4 = load float, ptr %arrayidx.2, align 435 %arrayidx.3 = getelementptr inbounds float, ptr %x, i64 336 %l6 = load float, ptr %arrayidx.3, align 437 %l1 = tail call float @llvm.ldexp.f32.i32(float %l0, i32 %exp)38 %l3 = tail call float @llvm.ldexp.f32.i32(float %l2, i32 %exp)39 %l5 = tail call float @llvm.ldexp.f32.i32(float %l4, i32 %exp)40 %l7 = tail call float @llvm.ldexp.f32.i32(float %l6, i32 %exp)41 store float %l1, ptr %y, align 442 %arrayidx2.1 = getelementptr inbounds float, ptr %y, i64 143 store float %l3, ptr %arrayidx2.1, align 444 %arrayidx2.2 = getelementptr inbounds float, ptr %y, i64 245 store float %l5, ptr %arrayidx2.2, align 446 %arrayidx2.3 = getelementptr inbounds float, ptr %y, i64 347 store float %l7, ptr %arrayidx2.3, align 448 ret void49}50 51define void @ldexp_f64i32(ptr %x, ptr %y, i32 %exp) {52; CHECK-LABEL: @ldexp_f64i32(53; CHECK-NEXT: entry:54; CHECK-NEXT: [[L0:%.*]] = load double, ptr [[X:%.*]], align 455; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds double, ptr [[X]], i64 156; CHECK-NEXT: [[L2:%.*]] = load double, ptr [[ARRAYIDX_1]], align 457; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds double, ptr [[X]], i64 258; CHECK-NEXT: [[L4:%.*]] = load double, ptr [[ARRAYIDX_2]], align 459; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds double, ptr [[X]], i64 360; CHECK-NEXT: [[L6:%.*]] = load double, ptr [[ARRAYIDX_3]], align 461; CHECK-NEXT: [[L1:%.*]] = tail call double @llvm.ldexp.f64.i32(double [[L0]], i32 [[EXP:%.*]])62; CHECK-NEXT: [[L3:%.*]] = tail call double @llvm.ldexp.f64.i32(double [[L2]], i32 [[EXP]])63; CHECK-NEXT: [[L5:%.*]] = tail call double @llvm.ldexp.f64.i32(double [[L4]], i32 [[EXP]])64; CHECK-NEXT: [[L7:%.*]] = tail call double @llvm.ldexp.f64.i32(double [[L6]], i32 [[EXP]])65; CHECK-NEXT: store double [[L1]], ptr [[Y:%.*]], align 466; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds double, ptr [[Y]], i64 167; CHECK-NEXT: store double [[L3]], ptr [[ARRAYIDX2_1]], align 468; CHECK-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds double, ptr [[Y]], i64 269; CHECK-NEXT: store double [[L5]], ptr [[ARRAYIDX2_2]], align 470; CHECK-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds double, ptr [[Y]], i64 371; CHECK-NEXT: store double [[L7]], ptr [[ARRAYIDX2_3]], align 472; CHECK-NEXT: ret void73;74entry:75 %l0 = load double, ptr %x, align 476 %arrayidx.1 = getelementptr inbounds double, ptr %x, i64 177 %l2 = load double, ptr %arrayidx.1, align 478 %arrayidx.2 = getelementptr inbounds double, ptr %x, i64 279 %l4 = load double, ptr %arrayidx.2, align 480 %arrayidx.3 = getelementptr inbounds double, ptr %x, i64 381 %l6 = load double, ptr %arrayidx.3, align 482 %l1 = tail call double @llvm.ldexp.f64.i32(double %l0, i32 %exp)83 %l3 = tail call double @llvm.ldexp.f64.i32(double %l2, i32 %exp)84 %l5 = tail call double @llvm.ldexp.f64.i32(double %l4, i32 %exp)85 %l7 = tail call double @llvm.ldexp.f64.i32(double %l6, i32 %exp)86 store double %l1, ptr %y, align 487 %arrayidx2.1 = getelementptr inbounds double, ptr %y, i64 188 store double %l3, ptr %arrayidx2.1, align 489 %arrayidx2.2 = getelementptr inbounds double, ptr %y, i64 290 store double %l5, ptr %arrayidx2.2, align 491 %arrayidx2.3 = getelementptr inbounds double, ptr %y, i64 392 store double %l7, ptr %arrayidx2.3, align 493 ret void94}95 96define void @ldexp_f32i64(ptr %x, ptr %y, i64 %exp) {97; CHECK-LABEL: @ldexp_f32i64(98; CHECK-NEXT: entry:99; CHECK-NEXT: [[L0:%.*]] = load float, ptr [[X:%.*]], align 4100; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds float, ptr [[X]], i64 1101; CHECK-NEXT: [[L2:%.*]] = load float, ptr [[ARRAYIDX_1]], align 4102; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds float, ptr [[X]], i64 2103; CHECK-NEXT: [[L4:%.*]] = load float, ptr [[ARRAYIDX_2]], align 4104; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds float, ptr [[X]], i64 3105; CHECK-NEXT: [[L6:%.*]] = load float, ptr [[ARRAYIDX_3]], align 4106; CHECK-NEXT: [[L1:%.*]] = tail call float @llvm.ldexp.f32.i64(float [[L0]], i64 [[EXP:%.*]])107; CHECK-NEXT: [[L3:%.*]] = tail call float @llvm.ldexp.f32.i64(float [[L2]], i64 [[EXP]])108; CHECK-NEXT: [[L5:%.*]] = tail call float @llvm.ldexp.f32.i64(float [[L4]], i64 [[EXP]])109; CHECK-NEXT: [[L7:%.*]] = tail call float @llvm.ldexp.f32.i64(float [[L6]], i64 [[EXP]])110; CHECK-NEXT: store float [[L1]], ptr [[Y:%.*]], align 4111; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds float, ptr [[Y]], i64 1112; CHECK-NEXT: store float [[L3]], ptr [[ARRAYIDX2_1]], align 4113; CHECK-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds float, ptr [[Y]], i64 2114; CHECK-NEXT: store float [[L5]], ptr [[ARRAYIDX2_2]], align 4115; CHECK-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds float, ptr [[Y]], i64 3116; CHECK-NEXT: store float [[L7]], ptr [[ARRAYIDX2_3]], align 4117; CHECK-NEXT: ret void118;119entry:120 %l0 = load float, ptr %x, align 4121 %arrayidx.1 = getelementptr inbounds float, ptr %x, i64 1122 %l2 = load float, ptr %arrayidx.1, align 4123 %arrayidx.2 = getelementptr inbounds float, ptr %x, i64 2124 %l4 = load float, ptr %arrayidx.2, align 4125 %arrayidx.3 = getelementptr inbounds float, ptr %x, i64 3126 %l6 = load float, ptr %arrayidx.3, align 4127 %l1 = tail call float @llvm.ldexp.f32.i64(float %l0, i64 %exp)128 %l3 = tail call float @llvm.ldexp.f32.i64(float %l2, i64 %exp)129 %l5 = tail call float @llvm.ldexp.f32.i64(float %l4, i64 %exp)130 %l7 = tail call float @llvm.ldexp.f32.i64(float %l6, i64 %exp)131 store float %l1, ptr %y, align 4132 %arrayidx2.1 = getelementptr inbounds float, ptr %y, i64 1133 store float %l3, ptr %arrayidx2.1, align 4134 %arrayidx2.2 = getelementptr inbounds float, ptr %y, i64 2135 store float %l5, ptr %arrayidx2.2, align 4136 %arrayidx2.3 = getelementptr inbounds float, ptr %y, i64 3137 store float %l7, ptr %arrayidx2.3, align 4138 ret void139}140 141define void @ldexp_f64i64(ptr %x, ptr %y, i64 %exp) {142; CHECK-LABEL: @ldexp_f64i64(143; CHECK-NEXT: entry:144; CHECK-NEXT: [[L0:%.*]] = load double, ptr [[X:%.*]], align 4145; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds double, ptr [[X]], i64 1146; CHECK-NEXT: [[L2:%.*]] = load double, ptr [[ARRAYIDX_1]], align 4147; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds double, ptr [[X]], i64 2148; CHECK-NEXT: [[L4:%.*]] = load double, ptr [[ARRAYIDX_2]], align 4149; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds double, ptr [[X]], i64 3150; CHECK-NEXT: [[L6:%.*]] = load double, ptr [[ARRAYIDX_3]], align 4151; CHECK-NEXT: [[L1:%.*]] = tail call double @llvm.ldexp.f64.i64(double [[L0]], i64 [[EXP:%.*]])152; CHECK-NEXT: [[L3:%.*]] = tail call double @llvm.ldexp.f64.i64(double [[L2]], i64 [[EXP]])153; CHECK-NEXT: [[L5:%.*]] = tail call double @llvm.ldexp.f64.i64(double [[L4]], i64 [[EXP]])154; CHECK-NEXT: [[L7:%.*]] = tail call double @llvm.ldexp.f64.i64(double [[L6]], i64 [[EXP]])155; CHECK-NEXT: store double [[L1]], ptr [[Y:%.*]], align 4156; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds double, ptr [[Y]], i64 1157; CHECK-NEXT: store double [[L3]], ptr [[ARRAYIDX2_1]], align 4158; CHECK-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds double, ptr [[Y]], i64 2159; CHECK-NEXT: store double [[L5]], ptr [[ARRAYIDX2_2]], align 4160; CHECK-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds double, ptr [[Y]], i64 3161; CHECK-NEXT: store double [[L7]], ptr [[ARRAYIDX2_3]], align 4162; CHECK-NEXT: ret void163;164entry:165 %l0 = load double, ptr %x, align 4166 %arrayidx.1 = getelementptr inbounds double, ptr %x, i64 1167 %l2 = load double, ptr %arrayidx.1, align 4168 %arrayidx.2 = getelementptr inbounds double, ptr %x, i64 2169 %l4 = load double, ptr %arrayidx.2, align 4170 %arrayidx.3 = getelementptr inbounds double, ptr %x, i64 3171 %l6 = load double, ptr %arrayidx.3, align 4172 %l1 = tail call double @llvm.ldexp.f64.i64(double %l0, i64 %exp)173 %l3 = tail call double @llvm.ldexp.f64.i64(double %l2, i64 %exp)174 %l5 = tail call double @llvm.ldexp.f64.i64(double %l4, i64 %exp)175 %l7 = tail call double @llvm.ldexp.f64.i64(double %l6, i64 %exp)176 store double %l1, ptr %y, align 4177 %arrayidx2.1 = getelementptr inbounds double, ptr %y, i64 1178 store double %l3, ptr %arrayidx2.1, align 4179 %arrayidx2.2 = getelementptr inbounds double, ptr %y, i64 2180 store double %l5, ptr %arrayidx2.2, align 4181 %arrayidx2.3 = getelementptr inbounds double, ptr %y, i64 3182 store double %l7, ptr %arrayidx2.3, align 4183 ret void184}185 186define void @ldexp_f32i32_i64(ptr %x, ptr %y, i32 %exp32, i64 %exp64) {187; CHECK-LABEL: @ldexp_f32i32_i64(188; CHECK-NEXT: entry:189; CHECK-NEXT: [[L0:%.*]] = load float, ptr [[X:%.*]], align 4190; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds float, ptr [[X]], i64 1191; CHECK-NEXT: [[L2:%.*]] = load float, ptr [[ARRAYIDX_1]], align 4192; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds float, ptr [[X]], i64 2193; CHECK-NEXT: [[L4:%.*]] = load float, ptr [[ARRAYIDX_2]], align 4194; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds float, ptr [[X]], i64 3195; CHECK-NEXT: [[L6:%.*]] = load float, ptr [[ARRAYIDX_3]], align 4196; CHECK-NEXT: [[L1:%.*]] = tail call float @llvm.ldexp.f32.i32(float [[L0]], i32 [[EXP32:%.*]])197; CHECK-NEXT: [[L3:%.*]] = tail call float @llvm.ldexp.f32.i32(float [[L2]], i32 [[EXP32]])198; CHECK-NEXT: [[L5:%.*]] = tail call float @llvm.ldexp.f32.i64(float [[L4]], i64 [[EXP64:%.*]])199; CHECK-NEXT: [[L7:%.*]] = tail call float @llvm.ldexp.f32.i64(float [[L6]], i64 [[EXP64]])200; CHECK-NEXT: store float [[L1]], ptr [[Y:%.*]], align 4201; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds float, ptr [[Y]], i64 1202; CHECK-NEXT: store float [[L3]], ptr [[ARRAYIDX2_1]], align 4203; CHECK-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds float, ptr [[Y]], i64 2204; CHECK-NEXT: store float [[L5]], ptr [[ARRAYIDX2_2]], align 4205; CHECK-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds float, ptr [[Y]], i64 3206; CHECK-NEXT: store float [[L7]], ptr [[ARRAYIDX2_3]], align 4207; CHECK-NEXT: ret void208;209entry:210 %l0 = load float, ptr %x, align 4211 %arrayidx.1 = getelementptr inbounds float, ptr %x, i64 1212 %l2 = load float, ptr %arrayidx.1, align 4213 %arrayidx.2 = getelementptr inbounds float, ptr %x, i64 2214 %l4 = load float, ptr %arrayidx.2, align 4215 %arrayidx.3 = getelementptr inbounds float, ptr %x, i64 3216 %l6 = load float, ptr %arrayidx.3, align 4217 %l1 = tail call float @llvm.ldexp.f32.i32(float %l0, i32 %exp32)218 %l3 = tail call float @llvm.ldexp.f32.i32(float %l2, i32 %exp32)219 %l5 = tail call float @llvm.ldexp.f32.i64(float %l4, i64 %exp64)220 %l7 = tail call float @llvm.ldexp.f32.i64(float %l6, i64 %exp64)221 store float %l1, ptr %y, align 4222 %arrayidx2.1 = getelementptr inbounds float, ptr %y, i64 1223 store float %l3, ptr %arrayidx2.1, align 4224 %arrayidx2.2 = getelementptr inbounds float, ptr %y, i64 2225 store float %l5, ptr %arrayidx2.2, align 4226 %arrayidx2.3 = getelementptr inbounds float, ptr %y, i64 3227 store float %l7, ptr %arrayidx2.3, align 4228 ret void229}230 231define void @ldexp_f64_i32_i64(ptr %x, ptr %y, i32 %exp32, i64 %exp64) {232; CHECK-LABEL: @ldexp_f64_i32_i64(233; CHECK-NEXT: entry:234; CHECK-NEXT: [[L0:%.*]] = load double, ptr [[X:%.*]], align 4235; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds double, ptr [[X]], i64 1236; CHECK-NEXT: [[L2:%.*]] = load double, ptr [[ARRAYIDX_1]], align 4237; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds double, ptr [[X]], i64 2238; CHECK-NEXT: [[L4:%.*]] = load double, ptr [[ARRAYIDX_2]], align 4239; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds double, ptr [[X]], i64 3240; CHECK-NEXT: [[L6:%.*]] = load double, ptr [[ARRAYIDX_3]], align 4241; CHECK-NEXT: [[L1:%.*]] = tail call double @llvm.ldexp.f64.i32(double [[L0]], i32 [[EXP32:%.*]])242; CHECK-NEXT: [[L3:%.*]] = tail call double @llvm.ldexp.f64.i32(double [[L2]], i32 [[EXP32]])243; CHECK-NEXT: [[L5:%.*]] = tail call double @llvm.ldexp.f64.i64(double [[L4]], i64 [[EXP64:%.*]])244; CHECK-NEXT: [[L7:%.*]] = tail call double @llvm.ldexp.f64.i64(double [[L6]], i64 [[EXP64]])245; CHECK-NEXT: store double [[L1]], ptr [[Y:%.*]], align 4246; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds double, ptr [[Y]], i64 1247; CHECK-NEXT: store double [[L3]], ptr [[ARRAYIDX2_1]], align 4248; CHECK-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds double, ptr [[Y]], i64 2249; CHECK-NEXT: store double [[L5]], ptr [[ARRAYIDX2_2]], align 4250; CHECK-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds double, ptr [[Y]], i64 3251; CHECK-NEXT: store double [[L7]], ptr [[ARRAYIDX2_3]], align 4252; CHECK-NEXT: ret void253;254entry:255 %l0 = load double, ptr %x, align 4256 %arrayidx.1 = getelementptr inbounds double, ptr %x, i64 1257 %l2 = load double, ptr %arrayidx.1, align 4258 %arrayidx.2 = getelementptr inbounds double, ptr %x, i64 2259 %l4 = load double, ptr %arrayidx.2, align 4260 %arrayidx.3 = getelementptr inbounds double, ptr %x, i64 3261 %l6 = load double, ptr %arrayidx.3, align 4262 %l1 = tail call double @llvm.ldexp.f64.i32(double %l0, i32 %exp32)263 %l3 = tail call double @llvm.ldexp.f64.i32(double %l2, i32 %exp32)264 %l5 = tail call double @llvm.ldexp.f64.i64(double %l4, i64 %exp64)265 %l7 = tail call double @llvm.ldexp.f64.i64(double %l6, i64 %exp64)266 store double %l1, ptr %y, align 4267 %arrayidx2.1 = getelementptr inbounds double, ptr %y, i64 1268 store double %l3, ptr %arrayidx2.1, align 4269 %arrayidx2.2 = getelementptr inbounds double, ptr %y, i64 2270 store double %l5, ptr %arrayidx2.2, align 4271 %arrayidx2.3 = getelementptr inbounds double, ptr %y, i64 3272 store double %l7, ptr %arrayidx2.3, align 4273 ret void274}275 276declare float @llvm.ldexp.f32.i32(float, i32)277declare double @llvm.ldexp.f64.i32(double, i32)278declare float @llvm.ldexp.f32.i64(float, i64)279declare double @llvm.ldexp.f64.i64(double, i64)280