633 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s --check-prefixes=CHECK,CHECK-NEON3; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=-neon | FileCheck %s --check-prefixes=CHECK,CHECK-NO-NEON4 5declare i16 @llvm.umax.i16(i16, i16)6declare i64 @llvm.umin.i64(i64, i64)7 8declare <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float>, <4 x i32>)9 10define <4 x float> @fmul_pow2_4xfloat(<4 x i32> %i) {11; CHECK-NEON-LABEL: fmul_pow2_4xfloat:12; CHECK-NEON: // %bb.0:13; CHECK-NEON-NEXT: movi v1.4s, #114; CHECK-NEON-NEXT: ushl v0.4s, v1.4s, v0.4s15; CHECK-NEON-NEXT: fmov v1.4s, #9.0000000016; CHECK-NEON-NEXT: ucvtf v0.4s, v0.4s17; CHECK-NEON-NEXT: fmul v0.4s, v0.4s, v1.4s18; CHECK-NEON-NEXT: ret19;20; CHECK-NO-NEON-LABEL: fmul_pow2_4xfloat:21; CHECK-NO-NEON: // %bb.0:22; CHECK-NO-NEON-NEXT: mov w8, #1 // =0x123; CHECK-NO-NEON-NEXT: fmov s3, #9.0000000024; CHECK-NO-NEON-NEXT: lsl w9, w8, w025; CHECK-NO-NEON-NEXT: lsl w10, w8, w126; CHECK-NO-NEON-NEXT: lsl w11, w8, w227; CHECK-NO-NEON-NEXT: lsl w8, w8, w328; CHECK-NO-NEON-NEXT: ucvtf s1, w1029; CHECK-NO-NEON-NEXT: ucvtf s0, w930; CHECK-NO-NEON-NEXT: ucvtf s2, w1131; CHECK-NO-NEON-NEXT: ucvtf s4, w832; CHECK-NO-NEON-NEXT: fmul s0, s0, s333; CHECK-NO-NEON-NEXT: fmul s1, s1, s334; CHECK-NO-NEON-NEXT: fmul s2, s2, s335; CHECK-NO-NEON-NEXT: fmul s3, s4, s336; CHECK-NO-NEON-NEXT: ret37 %p2 = shl <4 x i32> <i32 1, i32 1, i32 1, i32 1>, %i38 %p2_f = uitofp <4 x i32> %p2 to <4 x float>39 %r = fmul <4 x float> <float 9.000000e+00, float 9.000000e+00, float 9.000000e+00, float 9.000000e+00>, %p2_f40 ret <4 x float> %r41}42 43define <4 x float> @fmul_pow2_ldexp_4xfloat(<4 x i32> %i) {44; CHECK-NEON-LABEL: fmul_pow2_ldexp_4xfloat:45; CHECK-NEON: // %bb.0:46; CHECK-NEON-NEXT: sub sp, sp, #4847; CHECK-NEON-NEXT: str x30, [sp, #32] // 8-byte Spill48; CHECK-NEON-NEXT: .cfi_def_cfa_offset 4849; CHECK-NEON-NEXT: .cfi_offset w30, -1650; CHECK-NEON-NEXT: mov w0, v0.s[1]51; CHECK-NEON-NEXT: str q0, [sp, #16] // 16-byte Spill52; CHECK-NEON-NEXT: fmov s0, #9.0000000053; CHECK-NEON-NEXT: bl ldexpf54; CHECK-NEON-NEXT: ldr q1, [sp, #16] // 16-byte Reload55; CHECK-NEON-NEXT: // kill: def $s0 killed $s0 def $q056; CHECK-NEON-NEXT: str q0, [sp] // 16-byte Spill57; CHECK-NEON-NEXT: fmov s0, #9.0000000058; CHECK-NEON-NEXT: fmov w0, s159; CHECK-NEON-NEXT: bl ldexpf60; CHECK-NEON-NEXT: ldr q1, [sp] // 16-byte Reload61; CHECK-NEON-NEXT: // kill: def $s0 killed $s0 def $q062; CHECK-NEON-NEXT: mov v0.s[1], v1.s[0]63; CHECK-NEON-NEXT: str q0, [sp] // 16-byte Spill64; CHECK-NEON-NEXT: ldr q0, [sp, #16] // 16-byte Reload65; CHECK-NEON-NEXT: mov w0, v0.s[2]66; CHECK-NEON-NEXT: fmov s0, #9.0000000067; CHECK-NEON-NEXT: bl ldexpf68; CHECK-NEON-NEXT: ldr q1, [sp] // 16-byte Reload69; CHECK-NEON-NEXT: // kill: def $s0 killed $s0 def $q070; CHECK-NEON-NEXT: mov v1.s[2], v0.s[0]71; CHECK-NEON-NEXT: ldr q0, [sp, #16] // 16-byte Reload72; CHECK-NEON-NEXT: mov w0, v0.s[3]73; CHECK-NEON-NEXT: fmov s0, #9.0000000074; CHECK-NEON-NEXT: str q1, [sp] // 16-byte Spill75; CHECK-NEON-NEXT: bl ldexpf76; CHECK-NEON-NEXT: ldr q1, [sp] // 16-byte Reload77; CHECK-NEON-NEXT: // kill: def $s0 killed $s0 def $q078; CHECK-NEON-NEXT: ldr x30, [sp, #32] // 8-byte Reload79; CHECK-NEON-NEXT: mov v1.s[3], v0.s[0]80; CHECK-NEON-NEXT: mov v0.16b, v1.16b81; CHECK-NEON-NEXT: add sp, sp, #4882; CHECK-NEON-NEXT: ret83;84; CHECK-NO-NEON-LABEL: fmul_pow2_ldexp_4xfloat:85; CHECK-NO-NEON: // %bb.0:86; CHECK-NO-NEON-NEXT: str d10, [sp, #-64]! // 8-byte Folded Spill87; CHECK-NO-NEON-NEXT: stp d9, d8, [sp, #16] // 16-byte Folded Spill88; CHECK-NO-NEON-NEXT: stp x30, x21, [sp, #32] // 16-byte Folded Spill89; CHECK-NO-NEON-NEXT: stp x20, x19, [sp, #48] // 16-byte Folded Spill90; CHECK-NO-NEON-NEXT: .cfi_def_cfa_offset 6491; CHECK-NO-NEON-NEXT: .cfi_offset w19, -892; CHECK-NO-NEON-NEXT: .cfi_offset w20, -1693; CHECK-NO-NEON-NEXT: .cfi_offset w21, -2494; CHECK-NO-NEON-NEXT: .cfi_offset w30, -3295; CHECK-NO-NEON-NEXT: .cfi_offset b8, -4096; CHECK-NO-NEON-NEXT: .cfi_offset b9, -4897; CHECK-NO-NEON-NEXT: .cfi_offset b10, -6498; CHECK-NO-NEON-NEXT: fmov s0, #9.0000000099; CHECK-NO-NEON-NEXT: mov w19, w3100; CHECK-NO-NEON-NEXT: mov w20, w2101; CHECK-NO-NEON-NEXT: mov w21, w1102; CHECK-NO-NEON-NEXT: bl ldexpf103; CHECK-NO-NEON-NEXT: fmov s8, s0104; CHECK-NO-NEON-NEXT: fmov s0, #9.00000000105; CHECK-NO-NEON-NEXT: mov w0, w21106; CHECK-NO-NEON-NEXT: bl ldexpf107; CHECK-NO-NEON-NEXT: fmov s9, s0108; CHECK-NO-NEON-NEXT: fmov s0, #9.00000000109; CHECK-NO-NEON-NEXT: mov w0, w20110; CHECK-NO-NEON-NEXT: bl ldexpf111; CHECK-NO-NEON-NEXT: fmov s10, s0112; CHECK-NO-NEON-NEXT: fmov s0, #9.00000000113; CHECK-NO-NEON-NEXT: mov w0, w19114; CHECK-NO-NEON-NEXT: bl ldexpf115; CHECK-NO-NEON-NEXT: fmov s3, s0116; CHECK-NO-NEON-NEXT: fmov s0, s8117; CHECK-NO-NEON-NEXT: fmov s1, s9118; CHECK-NO-NEON-NEXT: ldp x20, x19, [sp, #48] // 16-byte Folded Reload119; CHECK-NO-NEON-NEXT: fmov s2, s10120; CHECK-NO-NEON-NEXT: ldp x30, x21, [sp, #32] // 16-byte Folded Reload121; CHECK-NO-NEON-NEXT: ldp d9, d8, [sp, #16] // 16-byte Folded Reload122; CHECK-NO-NEON-NEXT: ldr d10, [sp], #64 // 8-byte Folded Reload123; CHECK-NO-NEON-NEXT: ret124 %r = call <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float> <float 9.000000e+00, float 9.000000e+00, float 9.000000e+00, float 9.000000e+00>, <4 x i32> %i)125 ret <4 x float> %r126}127 128define <4 x float> @fdiv_pow2_4xfloat(<4 x i32> %i) {129; CHECK-NEON-LABEL: fdiv_pow2_4xfloat:130; CHECK-NEON: // %bb.0:131; CHECK-NEON-NEXT: fmov v1.4s, #9.00000000132; CHECK-NEON-NEXT: shl v0.4s, v0.4s, #23133; CHECK-NEON-NEXT: sub v0.4s, v1.4s, v0.4s134; CHECK-NEON-NEXT: ret135;136; CHECK-NO-NEON-LABEL: fdiv_pow2_4xfloat:137; CHECK-NO-NEON: // %bb.0:138; CHECK-NO-NEON-NEXT: mov w8, #1091567616 // =0x41100000139; CHECK-NO-NEON-NEXT: sub w9, w8, w0, lsl #23140; CHECK-NO-NEON-NEXT: sub w10, w8, w1, lsl #23141; CHECK-NO-NEON-NEXT: sub w11, w8, w2, lsl #23142; CHECK-NO-NEON-NEXT: sub w8, w8, w3, lsl #23143; CHECK-NO-NEON-NEXT: fmov s0, w9144; CHECK-NO-NEON-NEXT: fmov s1, w10145; CHECK-NO-NEON-NEXT: fmov s2, w11146; CHECK-NO-NEON-NEXT: fmov s3, w8147; CHECK-NO-NEON-NEXT: ret148 %p2 = shl <4 x i32> <i32 1, i32 1, i32 1, i32 1>, %i149 %p2_f = uitofp <4 x i32> %p2 to <4 x float>150 %r = fdiv <4 x float> <float 9.000000e+00, float 9.000000e+00, float 9.000000e+00, float 9.000000e+00>, %p2_f151 ret <4 x float> %r152}153 154define double @fmul_pow_shl_cnt(i64 %cnt) nounwind {155; CHECK-LABEL: fmul_pow_shl_cnt:156; CHECK: // %bb.0:157; CHECK-NEXT: mov w8, #1 // =0x1158; CHECK-NEXT: fmov d1, #9.00000000159; CHECK-NEXT: lsl x8, x8, x0160; CHECK-NEXT: ucvtf d0, x8161; CHECK-NEXT: fmul d0, d0, d1162; CHECK-NEXT: ret163 %shl = shl nuw i64 1, %cnt164 %conv = uitofp i64 %shl to double165 %mul = fmul double 9.000000e+00, %conv166 ret double %mul167}168 169define double @fmul_pow_shl_cnt2(i64 %cnt) nounwind {170; CHECK-LABEL: fmul_pow_shl_cnt2:171; CHECK: // %bb.0:172; CHECK-NEXT: mov w8, #2 // =0x2173; CHECK-NEXT: fmov d1, #-9.00000000174; CHECK-NEXT: lsl x8, x8, x0175; CHECK-NEXT: ucvtf d0, x8176; CHECK-NEXT: fmul d0, d0, d1177; CHECK-NEXT: ret178 %shl = shl nuw i64 2, %cnt179 %conv = uitofp i64 %shl to double180 %mul = fmul double -9.000000e+00, %conv181 ret double %mul182}183 184define float @fmul_pow_select(i32 %cnt, i1 %c) nounwind {185; CHECK-LABEL: fmul_pow_select:186; CHECK: // %bb.0:187; CHECK-NEXT: mov w8, #1 // =0x1188; CHECK-NEXT: tst w1, #0x1189; CHECK-NEXT: fmov s1, #9.00000000190; CHECK-NEXT: cinc w8, w8, eq191; CHECK-NEXT: lsl w8, w8, w0192; CHECK-NEXT: ucvtf s0, w8193; CHECK-NEXT: fmul s0, s0, s1194; CHECK-NEXT: ret195 %shl2 = shl nuw i32 2, %cnt196 %shl1 = shl nuw i32 1, %cnt197 %shl = select i1 %c, i32 %shl1, i32 %shl2198 %conv = uitofp i32 %shl to float199 %mul = fmul float 9.000000e+00, %conv200 ret float %mul201}202 203define float @fmul_fly_pow_mul_min_pow2(i64 %cnt) nounwind {204; CHECK-LABEL: fmul_fly_pow_mul_min_pow2:205; CHECK: // %bb.0:206; CHECK-NEXT: mov w8, #8 // =0x8207; CHECK-NEXT: mov w9, #8192 // =0x2000208; CHECK-NEXT: fmov s1, #9.00000000209; CHECK-NEXT: lsl x8, x8, x0210; CHECK-NEXT: cmp x8, #2, lsl #12 // =8192211; CHECK-NEXT: csel x8, x8, x9, lo212; CHECK-NEXT: ucvtf s0, x8213; CHECK-NEXT: fmul s0, s0, s1214; CHECK-NEXT: ret215 %shl8 = shl nuw i64 8, %cnt216 %shl = call i64 @llvm.umin.i64(i64 %shl8, i64 8192)217 %conv = uitofp i64 %shl to float218 %mul = fmul float 9.000000e+00, %conv219 ret float %mul220}221 222define double @fmul_pow_mul_max_pow2(i16 %cnt) nounwind {223; CHECK-LABEL: fmul_pow_mul_max_pow2:224; CHECK: // %bb.0:225; CHECK-NEXT: mov w8, #2 // =0x2226; CHECK-NEXT: mov w9, #1 // =0x1227; CHECK-NEXT: fmov d1, #3.00000000228; CHECK-NEXT: lsl w8, w8, w0229; CHECK-NEXT: lsl w9, w9, w0230; CHECK-NEXT: and w8, w8, #0xfffe231; CHECK-NEXT: and w9, w9, #0xffff232; CHECK-NEXT: cmp w9, w8233; CHECK-NEXT: csel w8, w9, w8, hi234; CHECK-NEXT: ucvtf d0, w8235; CHECK-NEXT: fmul d0, d0, d1236; CHECK-NEXT: ret237 %shl2 = shl nuw i16 2, %cnt238 %shl1 = shl nuw i16 1, %cnt239 %shl = call i16 @llvm.umax.i16(i16 %shl1, i16 %shl2)240 %conv = uitofp i16 %shl to double241 %mul = fmul double 3.000000e+00, %conv242 ret double %mul243}244 245define double @fmul_pow_shl_cnt_fail_maybe_non_pow2(i64 %v, i64 %cnt) nounwind {246; CHECK-LABEL: fmul_pow_shl_cnt_fail_maybe_non_pow2:247; CHECK: // %bb.0:248; CHECK-NEXT: lsl x8, x0, x1249; CHECK-NEXT: fmov d1, #9.00000000250; CHECK-NEXT: ucvtf d0, x8251; CHECK-NEXT: fmul d0, d0, d1252; CHECK-NEXT: ret253 %shl = shl nuw i64 %v, %cnt254 %conv = uitofp i64 %shl to double255 %mul = fmul double 9.000000e+00, %conv256 ret double %mul257}258 259define <2 x float> @fmul_pow_shl_cnt_vec_fail_expensive_cast(<2 x i64> %cnt) nounwind {260; CHECK-NEON-LABEL: fmul_pow_shl_cnt_vec_fail_expensive_cast:261; CHECK-NEON: // %bb.0:262; CHECK-NEON-NEXT: mov w8, #2 // =0x2263; CHECK-NEON-NEXT: dup v1.2d, x8264; CHECK-NEON-NEXT: ushl v0.2d, v1.2d, v0.2d265; CHECK-NEON-NEXT: mov x8, v0.d[1]266; CHECK-NEON-NEXT: fmov x9, d0267; CHECK-NEON-NEXT: ucvtf s1, x9268; CHECK-NEON-NEXT: ucvtf s0, x8269; CHECK-NEON-NEXT: mov v1.s[1], v0.s[0]270; CHECK-NEON-NEXT: fmov v0.2s, #15.00000000271; CHECK-NEON-NEXT: fmul v0.2s, v1.2s, v0.2s272; CHECK-NEON-NEXT: ret273;274; CHECK-NO-NEON-LABEL: fmul_pow_shl_cnt_vec_fail_expensive_cast:275; CHECK-NO-NEON: // %bb.0:276; CHECK-NO-NEON-NEXT: mov w8, #2 // =0x2277; CHECK-NO-NEON-NEXT: fmov s2, #15.00000000278; CHECK-NO-NEON-NEXT: lsl x9, x8, x0279; CHECK-NO-NEON-NEXT: lsl x8, x8, x1280; CHECK-NO-NEON-NEXT: ucvtf s1, x8281; CHECK-NO-NEON-NEXT: ucvtf s0, x9282; CHECK-NO-NEON-NEXT: fmul s0, s0, s2283; CHECK-NO-NEON-NEXT: fmul s1, s1, s2284; CHECK-NO-NEON-NEXT: ret285 %shl = shl nsw nuw <2 x i64> <i64 2, i64 2>, %cnt286 %conv = uitofp <2 x i64> %shl to <2 x float>287 %mul = fmul <2 x float> <float 15.000000e+00, float 15.000000e+00>, %conv288 ret <2 x float> %mul289}290 291define <2 x double> @fmul_pow_shl_cnt_vec(<2 x i64> %cnt) nounwind {292; CHECK-NEON-LABEL: fmul_pow_shl_cnt_vec:293; CHECK-NEON: // %bb.0:294; CHECK-NEON-NEXT: mov w8, #2 // =0x2295; CHECK-NEON-NEXT: dup v1.2d, x8296; CHECK-NEON-NEXT: ushl v0.2d, v1.2d, v0.2d297; CHECK-NEON-NEXT: fmov v1.2d, #15.00000000298; CHECK-NEON-NEXT: ucvtf v0.2d, v0.2d299; CHECK-NEON-NEXT: fmul v0.2d, v0.2d, v1.2d300; CHECK-NEON-NEXT: ret301;302; CHECK-NO-NEON-LABEL: fmul_pow_shl_cnt_vec:303; CHECK-NO-NEON: // %bb.0:304; CHECK-NO-NEON-NEXT: mov w8, #2 // =0x2305; CHECK-NO-NEON-NEXT: fmov d2, #15.00000000306; CHECK-NO-NEON-NEXT: lsl x9, x8, x0307; CHECK-NO-NEON-NEXT: lsl x8, x8, x1308; CHECK-NO-NEON-NEXT: ucvtf d1, x8309; CHECK-NO-NEON-NEXT: ucvtf d0, x9310; CHECK-NO-NEON-NEXT: fmul d0, d0, d2311; CHECK-NO-NEON-NEXT: fmul d1, d1, d2312; CHECK-NO-NEON-NEXT: ret313 %shl = shl nsw nuw <2 x i64> <i64 2, i64 2>, %cnt314 %conv = uitofp <2 x i64> %shl to <2 x double>315 %mul = fmul <2 x double> <double 15.000000e+00, double 15.000000e+00>, %conv316 ret <2 x double> %mul317}318 319define <4 x float> @fmul_pow_shl_cnt_vec_preserve_fma(<4 x i32> %cnt, <4 x float> %add) nounwind {320; CHECK-NEON-LABEL: fmul_pow_shl_cnt_vec_preserve_fma:321; CHECK-NEON: // %bb.0:322; CHECK-NEON-NEXT: movi v2.4s, #2323; CHECK-NEON-NEXT: ushl v0.4s, v2.4s, v0.4s324; CHECK-NEON-NEXT: fmov v2.4s, #5.00000000325; CHECK-NEON-NEXT: ucvtf v0.4s, v0.4s326; CHECK-NEON-NEXT: fmul v0.4s, v0.4s, v2.4s327; CHECK-NEON-NEXT: fadd v0.4s, v0.4s, v1.4s328; CHECK-NEON-NEXT: ret329;330; CHECK-NO-NEON-LABEL: fmul_pow_shl_cnt_vec_preserve_fma:331; CHECK-NO-NEON: // %bb.0:332; CHECK-NO-NEON-NEXT: mov w8, #2 // =0x2333; CHECK-NO-NEON-NEXT: fmov s16, #5.00000000334; CHECK-NO-NEON-NEXT: lsl w9, w8, w3335; CHECK-NO-NEON-NEXT: lsl w10, w8, w0336; CHECK-NO-NEON-NEXT: lsl w11, w8, w2337; CHECK-NO-NEON-NEXT: lsl w8, w8, w1338; CHECK-NO-NEON-NEXT: ucvtf s4, w10339; CHECK-NO-NEON-NEXT: ucvtf s5, w9340; CHECK-NO-NEON-NEXT: ucvtf s7, w11341; CHECK-NO-NEON-NEXT: ucvtf s6, w8342; CHECK-NO-NEON-NEXT: fmul s5, s5, s16343; CHECK-NO-NEON-NEXT: fmul s4, s4, s16344; CHECK-NO-NEON-NEXT: fmul s7, s7, s16345; CHECK-NO-NEON-NEXT: fmul s6, s6, s16346; CHECK-NO-NEON-NEXT: fadd s0, s4, s0347; CHECK-NO-NEON-NEXT: fadd s3, s5, s3348; CHECK-NO-NEON-NEXT: fadd s1, s6, s1349; CHECK-NO-NEON-NEXT: fadd s2, s7, s2350; CHECK-NO-NEON-NEXT: ret351 %shl = shl nsw nuw <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %cnt352 %conv = uitofp <4 x i32> %shl to <4 x float>353 %mul = fmul <4 x float> <float 5.000000e+00, float 5.000000e+00, float 5.000000e+00, float 5.000000e+00>, %conv354 %res = fadd <4 x float> %mul, %add355 ret <4 x float> %res356}357 358define <2 x double> @fmul_pow_shl_cnt_vec_non_splat_todo(<2 x i64> %cnt) nounwind {359; CHECK-NEON-LABEL: fmul_pow_shl_cnt_vec_non_splat_todo:360; CHECK-NEON: // %bb.0:361; CHECK-NEON-NEXT: mov w8, #2 // =0x2362; CHECK-NEON-NEXT: dup v1.2d, x8363; CHECK-NEON-NEXT: adrp x8, .LCPI12_0364; CHECK-NEON-NEXT: ushl v0.2d, v1.2d, v0.2d365; CHECK-NEON-NEXT: ldr q1, [x8, :lo12:.LCPI12_0]366; CHECK-NEON-NEXT: ucvtf v0.2d, v0.2d367; CHECK-NEON-NEXT: fmul v0.2d, v0.2d, v1.2d368; CHECK-NEON-NEXT: ret369;370; CHECK-NO-NEON-LABEL: fmul_pow_shl_cnt_vec_non_splat_todo:371; CHECK-NO-NEON: // %bb.0:372; CHECK-NO-NEON-NEXT: mov w8, #2 // =0x2373; CHECK-NO-NEON-NEXT: fmov d2, #15.00000000374; CHECK-NO-NEON-NEXT: fmov d3, #14.00000000375; CHECK-NO-NEON-NEXT: lsl x9, x8, x0376; CHECK-NO-NEON-NEXT: lsl x8, x8, x1377; CHECK-NO-NEON-NEXT: ucvtf d1, x8378; CHECK-NO-NEON-NEXT: ucvtf d0, x9379; CHECK-NO-NEON-NEXT: fmul d0, d0, d2380; CHECK-NO-NEON-NEXT: fmul d1, d1, d3381; CHECK-NO-NEON-NEXT: ret382 %shl = shl nsw nuw <2 x i64> <i64 2, i64 2>, %cnt383 %conv = uitofp <2 x i64> %shl to <2 x double>384 %mul = fmul <2 x double> <double 15.000000e+00, double 14.000000e+00>, %conv385 ret <2 x double> %mul386}387 388define <2 x double> @fmul_pow_shl_cnt_vec_non_splat2_todo(<2 x i64> %cnt) nounwind {389; CHECK-NEON-LABEL: fmul_pow_shl_cnt_vec_non_splat2_todo:390; CHECK-NEON: // %bb.0:391; CHECK-NEON-NEXT: adrp x8, .LCPI13_0392; CHECK-NEON-NEXT: ldr q1, [x8, :lo12:.LCPI13_0]393; CHECK-NEON-NEXT: ushl v0.2d, v1.2d, v0.2d394; CHECK-NEON-NEXT: fmov v1.2d, #15.00000000395; CHECK-NEON-NEXT: ucvtf v0.2d, v0.2d396; CHECK-NEON-NEXT: fmul v0.2d, v0.2d, v1.2d397; CHECK-NEON-NEXT: ret398;399; CHECK-NO-NEON-LABEL: fmul_pow_shl_cnt_vec_non_splat2_todo:400; CHECK-NO-NEON: // %bb.0:401; CHECK-NO-NEON-NEXT: mov w8, #2 // =0x2402; CHECK-NO-NEON-NEXT: mov w9, #1 // =0x1403; CHECK-NO-NEON-NEXT: fmov d2, #15.00000000404; CHECK-NO-NEON-NEXT: lsl x8, x8, x0405; CHECK-NO-NEON-NEXT: lsl x9, x9, x1406; CHECK-NO-NEON-NEXT: ucvtf d1, x9407; CHECK-NO-NEON-NEXT: ucvtf d0, x8408; CHECK-NO-NEON-NEXT: fmul d0, d0, d2409; CHECK-NO-NEON-NEXT: fmul d1, d1, d2410; CHECK-NO-NEON-NEXT: ret411 %shl = shl nsw nuw <2 x i64> <i64 2, i64 1>, %cnt412 %conv = uitofp <2 x i64> %shl to <2 x double>413 %mul = fmul <2 x double> <double 15.000000e+00, double 15.000000e+00>, %conv414 ret <2 x double> %mul415}416 417 418define double @fmul_pow_shl_cnt_fail_maybe_bad_exp(i64 %cnt) nounwind {419; CHECK-LABEL: fmul_pow_shl_cnt_fail_maybe_bad_exp:420; CHECK: // %bb.0:421; CHECK-NEXT: mov w8, #1 // =0x1422; CHECK-NEXT: lsl x8, x8, x0423; CHECK-NEXT: ucvtf d0, x8424; CHECK-NEXT: adrp x8, .LCPI14_0425; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI14_0]426; CHECK-NEXT: fmul d0, d0, d1427; CHECK-NEXT: ret428 %shl = shl nuw i64 1, %cnt429 %conv = uitofp i64 %shl to double430 %mul = fmul double 9.745314e+288, %conv431 ret double %mul432}433 434define double @fmul_pow_shl_cnt_safe(i16 %cnt) nounwind {435; CHECK-LABEL: fmul_pow_shl_cnt_safe:436; CHECK: // %bb.0:437; CHECK-NEXT: mov w8, #1 // =0x1438; CHECK-NEXT: lsl w8, w8, w0439; CHECK-NEXT: and w8, w8, #0xffff440; CHECK-NEXT: ucvtf d0, w8441; CHECK-NEXT: adrp x8, .LCPI15_0442; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI15_0]443; CHECK-NEXT: fmul d0, d0, d1444; CHECK-NEXT: ret445 %shl = shl nuw i16 1, %cnt446 %conv = uitofp i16 %shl to double447 %mul = fmul double 9.745314e+288, %conv448 ret double %mul449}450 451define <2 x double> @fdiv_pow_shl_cnt_vec(<2 x i64> %cnt) nounwind {452; CHECK-NEON-LABEL: fdiv_pow_shl_cnt_vec:453; CHECK-NEON: // %bb.0:454; CHECK-NEON-NEXT: fmov v1.2d, #1.00000000455; CHECK-NEON-NEXT: shl v0.2d, v0.2d, #52456; CHECK-NEON-NEXT: sub v0.2d, v1.2d, v0.2d457; CHECK-NEON-NEXT: ret458;459; CHECK-NO-NEON-LABEL: fdiv_pow_shl_cnt_vec:460; CHECK-NO-NEON: // %bb.0:461; CHECK-NO-NEON-NEXT: mov x8, #4607182418800017408 // =0x3ff0000000000000462; CHECK-NO-NEON-NEXT: sub x9, x8, x0, lsl #52463; CHECK-NO-NEON-NEXT: sub x8, x8, x1, lsl #52464; CHECK-NO-NEON-NEXT: fmov d0, x9465; CHECK-NO-NEON-NEXT: fmov d1, x8466; CHECK-NO-NEON-NEXT: ret467 %shl = shl nuw <2 x i64> <i64 1, i64 1>, %cnt468 %conv = uitofp <2 x i64> %shl to <2 x double>469 %mul = fdiv <2 x double> <double 1.000000e+00, double 1.000000e+00>, %conv470 ret <2 x double> %mul471}472 473define <2 x float> @fdiv_pow_shl_cnt_vec_with_expensive_cast(<2 x i64> %cnt) nounwind {474; CHECK-NEON-LABEL: fdiv_pow_shl_cnt_vec_with_expensive_cast:475; CHECK-NEON: // %bb.0:476; CHECK-NEON-NEXT: xtn v0.2s, v0.2d477; CHECK-NEON-NEXT: fmov v1.2s, #1.00000000478; CHECK-NEON-NEXT: shl v0.2s, v0.2s, #23479; CHECK-NEON-NEXT: sub v0.2s, v1.2s, v0.2s480; CHECK-NEON-NEXT: ret481;482; CHECK-NO-NEON-LABEL: fdiv_pow_shl_cnt_vec_with_expensive_cast:483; CHECK-NO-NEON: // %bb.0:484; CHECK-NO-NEON-NEXT: mov w8, #1065353216 // =0x3f800000485; CHECK-NO-NEON-NEXT: sub w9, w8, w0, lsl #23486; CHECK-NO-NEON-NEXT: sub w8, w8, w1, lsl #23487; CHECK-NO-NEON-NEXT: fmov s0, w9488; CHECK-NO-NEON-NEXT: fmov s1, w8489; CHECK-NO-NEON-NEXT: ret490 %shl = shl nuw <2 x i64> <i64 1, i64 1>, %cnt491 %conv = uitofp <2 x i64> %shl to <2 x float>492 %mul = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %conv493 ret <2 x float> %mul494}495 496define float @fdiv_pow_shl_cnt_fail_maybe_z(i64 %cnt) nounwind {497; CHECK-LABEL: fdiv_pow_shl_cnt_fail_maybe_z:498; CHECK: // %bb.0:499; CHECK-NEXT: mov w8, #8 // =0x8500; CHECK-NEXT: fmov s1, #-9.00000000501; CHECK-NEXT: lsl x8, x8, x0502; CHECK-NEXT: ucvtf s0, x8503; CHECK-NEXT: fdiv s0, s1, s0504; CHECK-NEXT: ret505 %shl = shl i64 8, %cnt506 %conv = uitofp i64 %shl to float507 %mul = fdiv float -9.000000e+00, %conv508 ret float %mul509}510 511define float @fdiv_pow_shl_cnt_fail_neg_int(i64 %cnt) nounwind {512; CHECK-LABEL: fdiv_pow_shl_cnt_fail_neg_int:513; CHECK: // %bb.0:514; CHECK-NEXT: mov w8, #8 // =0x8515; CHECK-NEXT: fmov s1, #-9.00000000516; CHECK-NEXT: lsl x8, x8, x0517; CHECK-NEXT: scvtf s0, x8518; CHECK-NEXT: fdiv s0, s1, s0519; CHECK-NEXT: ret520 %shl = shl i64 8, %cnt521 %conv = sitofp i64 %shl to float522 %mul = fdiv float -9.000000e+00, %conv523 ret float %mul524}525 526define float @fdiv_pow_shl_cnt(i64 %cnt_in) nounwind {527; CHECK-LABEL: fdiv_pow_shl_cnt:528; CHECK: // %bb.0:529; CHECK-NEXT: mov w8, #-1115684864 // =0xbd800000530; CHECK-NEXT: and w9, w0, #0x1f531; CHECK-NEXT: sub w8, w8, w9, lsl #23532; CHECK-NEXT: fmov s0, w8533; CHECK-NEXT: ret534 %cnt = and i64 %cnt_in, 31535 %shl = shl i64 8, %cnt536 %conv = sitofp i64 %shl to float537 %mul = fdiv float -0.500000e+00, %conv538 ret float %mul539}540 541define double @fdiv_pow_shl_cnt32_to_dbl_okay(i32 %cnt) nounwind {542; CHECK-LABEL: fdiv_pow_shl_cnt32_to_dbl_okay:543; CHECK: // %bb.0:544; CHECK-NEXT: mov x8, #3936146074321813504 // =0x36a0000000000000545; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0546; CHECK-NEXT: sub x8, x8, x0, lsl #52547; CHECK-NEXT: fmov d0, x8548; CHECK-NEXT: ret549 %shl = shl nuw i32 1, %cnt550 %conv = uitofp i32 %shl to double551 %mul = fdiv double 0x36A0000000000000, %conv552 ret double %mul553}554 555define float @fdiv_pow_shl_cnt32_out_of_bounds2(i32 %cnt) nounwind {556; CHECK-LABEL: fdiv_pow_shl_cnt32_out_of_bounds2:557; CHECK: // %bb.0:558; CHECK-NEXT: mov w8, #1 // =0x1559; CHECK-NEXT: lsl w8, w8, w0560; CHECK-NEXT: ucvtf s0, w8561; CHECK-NEXT: mov w8, #65528 // =0xfff8562; CHECK-NEXT: movk w8, #4351, lsl #16563; CHECK-NEXT: fmov s1, w8564; CHECK-NEXT: fdiv s0, s1, s0565; CHECK-NEXT: ret566 %shl = shl nuw i32 1, %cnt567 %conv = uitofp i32 %shl to float568 %mul = fdiv float 0x3a1fffff00000000, %conv569 ret float %mul570}571 572define float @fdiv_pow_shl_cnt32_okay(i32 %cnt) nounwind {573; CHECK-LABEL: fdiv_pow_shl_cnt32_okay:574; CHECK: // %bb.0:575; CHECK-NEXT: mov w8, #285212672 // =0x11000000576; CHECK-NEXT: sub w8, w8, w0, lsl #23577; CHECK-NEXT: fmov s0, w8578; CHECK-NEXT: ret579 %shl = shl nuw i32 1, %cnt580 %conv = uitofp i32 %shl to float581 %mul = fdiv float 0x3a20000000000000, %conv582 ret float %mul583}584 585define fastcc i1 @quantum_hadamard(i32 %0) {586; CHECK-LABEL: quantum_hadamard:587; CHECK: // %bb.0:588; CHECK-NEXT: mov x8, #4607182418800017408 // =0x3ff0000000000000589; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0590; CHECK-NEXT: sub x8, x8, x0, lsl #52591; CHECK-NEXT: fmov d0, x8592; CHECK-NEXT: fcvt s0, d0593; CHECK-NEXT: fcmp s0, #0.0594; CHECK-NEXT: cset w0, gt595; CHECK-NEXT: ret596 %2 = zext i32 %0 to i64597 %3 = shl i64 1, %2598 %4 = uitofp i64 %3 to double599 %5 = fdiv double 1.000000e+00, %4600 %6 = fptrunc double %5 to float601 %7 = fcmp olt float 0.000000e+00, %6602 ret i1 %7603}604 605define <vscale x 4 x float> @fdiv_pow2_nx4xfloat(<vscale x 4 x i32> %i) "target-features"="+sve" {606; CHECK-LABEL: fdiv_pow2_nx4xfloat:607; CHECK: // %bb.0:608; CHECK-NEXT: mov z1.s, #1 // =0x1609; CHECK-NEXT: ptrue p0.s610; CHECK-NEXT: lslr z0.s, p0/m, z0.s, z1.s611; CHECK-NEXT: fmov z1.s, #9.00000000612; CHECK-NEXT: ucvtf z0.s, p0/m, z0.s613; CHECK-NEXT: fdivr z0.s, p0/m, z0.s, z1.s614; CHECK-NEXT: ret615 %p2 = shl <vscale x 4 x i32> splat (i32 1), %i616 %p2_f = uitofp <vscale x 4 x i32> %p2 to <vscale x 4 x float>617 %r = fdiv <vscale x 4 x float> splat (float 9.000000e+00), %p2_f618 ret <vscale x 4 x float> %r619}620 621define <vscale x 2 x double> @scalable2(<vscale x 2 x i64> %0) "target-features"="+sve" {622; CHECK-LABEL: scalable2:623; CHECK: // %bb.0:624; CHECK-NEXT: ptrue p0.d625; CHECK-NEXT: fmov z1.d, #1.00000000626; CHECK-NEXT: ucvtf z0.d, p0/m, z0.d627; CHECK-NEXT: fdivr z0.d, p0/m, z0.d, z1.d628; CHECK-NEXT: ret629 %2 = uitofp <vscale x 2 x i64> %0 to <vscale x 2 x double>630 %3 = fdiv <vscale x 2 x double> splat (double 1.000000e+00), %2631 ret <vscale x 2 x double> %3632}633