454 lines · plain
1; RUN: llc -O0 -fast-isel -fast-isel-abort=1 -verify-machineinstrs -mtriple=arm64-apple-darwin -mcpu=cyclone < %s | FileCheck -enable-var-scope %s2 3;; Test various conversions.4define zeroext i32 @trunc_(i8 zeroext %a, i16 zeroext %b, i32 %c, i64 %d) nounwind ssp {5entry:6; CHECK-LABEL: trunc_7; CHECK: sub sp, sp, #168; CHECK: strb w0, [sp, #15]9; CHECK: strh w1, [sp, #12]10; CHECK: str w2, [sp, #8]11; CHECK: str x3, [sp]12; CHECK: ldr x8, [sp]13; CHECK: ; kill: def $w8 killed $w8 killed $x814; CHECK: str w8, [sp, #8]15; CHECK: ldr w8, [sp, #8]16; CHECK: strh w8, [sp, #12]17; CHECK: ldrh w8, [sp, #12]18; CHECK: strb w8, [sp, #15]19; CHECK: ldrb w0, [sp, #15]20; CHECK: add sp, sp, #1621; CHECK: ret22 %a.addr = alloca i8, align 123 %b.addr = alloca i16, align 224 %c.addr = alloca i32, align 425 %d.addr = alloca i64, align 826 store i8 %a, ptr %a.addr, align 127 store i16 %b, ptr %b.addr, align 228 store i32 %c, ptr %c.addr, align 429 store i64 %d, ptr %d.addr, align 830 %tmp = load i64, ptr %d.addr, align 831 %conv = trunc i64 %tmp to i3232 store i32 %conv, ptr %c.addr, align 433 %tmp1 = load i32, ptr %c.addr, align 434 %conv2 = trunc i32 %tmp1 to i1635 store i16 %conv2, ptr %b.addr, align 236 %tmp3 = load i16, ptr %b.addr, align 237 %conv4 = trunc i16 %tmp3 to i838 store i8 %conv4, ptr %a.addr, align 139 %tmp5 = load i8, ptr %a.addr, align 140 %conv6 = zext i8 %tmp5 to i3241 ret i32 %conv642}43 44define i64 @zext_(i8 zeroext %a, i16 zeroext %b, i32 %c, i64 %d) nounwind ssp {45entry:46; CHECK-LABEL: zext_47; CHECK: sub sp, sp, #1648; CHECK: strb w0, [sp, #15]49; CHECK: strh w1, [sp, #12]50; CHECK: str w2, [sp, #8]51; CHECK: str x3, [sp]52; CHECK: ldrb [[REG0:w[0-9]+]], [sp, #15]53; CHECK: strh [[REG0]], [sp, #12]54; CHECK: ldrh [[REG1:w[0-9]+]], [sp, #12]55; CHECK: str [[REG1]], [sp, #8]56; CHECK: ldr w[[REG2:[0-9]+]], [sp, #8]57; CHECK: str x[[REG2]], [sp]58; CHECK: ldr x0, [sp]59; CHECK: ret60 %a.addr = alloca i8, align 161 %b.addr = alloca i16, align 262 %c.addr = alloca i32, align 463 %d.addr = alloca i64, align 864 store i8 %a, ptr %a.addr, align 165 store i16 %b, ptr %b.addr, align 266 store i32 %c, ptr %c.addr, align 467 store i64 %d, ptr %d.addr, align 868 %tmp = load i8, ptr %a.addr, align 169 %conv = zext i8 %tmp to i1670 store i16 %conv, ptr %b.addr, align 271 %tmp1 = load i16, ptr %b.addr, align 272 %conv2 = zext i16 %tmp1 to i3273 store i32 %conv2, ptr %c.addr, align 474 %tmp3 = load i32, ptr %c.addr, align 475 %conv4 = zext i32 %tmp3 to i6476 store i64 %conv4, ptr %d.addr, align 877 %tmp5 = load i64, ptr %d.addr, align 878 ret i64 %tmp579}80 81define i32 @zext_i1_i32(i1 zeroext %a) nounwind ssp {82entry:83; CHECK-LABEL: zext_i1_i3284; CHECK-NOT: and w0, w0, #0x185; CHECK: ret86 %conv = zext i1 %a to i3287 ret i32 %conv;88}89 90define i64 @zext_i1_i64(i1 zeroext %a) nounwind ssp {91entry:92; CHECK-LABEL: zext_i1_i6493; CHECK-NOT: and w0, w0, #0x194; CHECK: ret95 %conv = zext i1 %a to i6496 ret i64 %conv;97}98 99define i64 @sext_(i8 signext %a, i16 signext %b, i32 %c, i64 %d) nounwind ssp {100entry:101; CHECK-LABEL: sext_102; CHECK: sub sp, sp, #16103; CHECK: strb w0, [sp, #15]104; CHECK: strh w1, [sp, #12]105; CHECK: str w2, [sp, #8]106; CHECK: str x3, [sp]107; CHECK: ldrsb [[REG0:w[0-9]+]], [sp, #15]108; CHECK: strh [[REG0]], [sp, #12]109; CHECK: ldrsh [[REG1:w[0-9]+]], [sp, #12]110; CHECK: str [[REG1]], [sp, #8]111; CHECK: ldrsw [[REG2:x[0-9]+]], [sp, #8]112; CHECK: str [[REG2]], [sp]113; CHECK: ldr x0, [sp]114; CHECK: ret115 %a.addr = alloca i8, align 1116 %b.addr = alloca i16, align 2117 %c.addr = alloca i32, align 4118 %d.addr = alloca i64, align 8119 store i8 %a, ptr %a.addr, align 1120 store i16 %b, ptr %b.addr, align 2121 store i32 %c, ptr %c.addr, align 4122 store i64 %d, ptr %d.addr, align 8123 %tmp = load i8, ptr %a.addr, align 1124 %conv = sext i8 %tmp to i16125 store i16 %conv, ptr %b.addr, align 2126 %tmp1 = load i16, ptr %b.addr, align 2127 %conv2 = sext i16 %tmp1 to i32128 store i32 %conv2, ptr %c.addr, align 4129 %tmp3 = load i32, ptr %c.addr, align 4130 %conv4 = sext i32 %tmp3 to i64131 store i64 %conv4, ptr %d.addr, align 8132 %tmp5 = load i64, ptr %d.addr, align 8133 ret i64 %tmp5134}135 136; Test sext i8 to i64137 138define zeroext i64 @sext_i8_i64(i8 zeroext %in) {139; CHECK-LABEL: sext_i8_i64:140; CHECK: mov x[[TMP:[0-9]+]], x0141; CHECK: sxtb x0, w[[TMP]]142 %big = sext i8 %in to i64143 ret i64 %big144}145 146define zeroext i64 @sext_i16_i64(i16 zeroext %in) {147; CHECK-LABEL: sext_i16_i64:148; CHECK: mov x[[TMP:[0-9]+]], x0149; CHECK: sxth x0, w[[TMP]]150 %big = sext i16 %in to i64151 ret i64 %big152}153 154; Test sext i1 to i32155define i32 @sext_i1_i32(i1 signext %a) nounwind ssp {156entry:157; CHECK-LABEL: sext_i1_i32158; CHECK-NOT: sbfx w0, w0, #0, #1159; CHECK: ret160 %conv = sext i1 %a to i32161 ret i32 %conv162}163 164; Test sext i1 to i16165define signext i16 @sext_i1_i16(i1 %a) nounwind ssp {166entry:167; CHECK-LABEL: sext_i1_i16168; CHECK: sbfx [[REG:w[0-9]+]], w0, #0, #1169; CHECK: sxth w0, [[REG]]170 %conv = sext i1 %a to i16171 ret i16 %conv172}173 174; Test sext i1 to i8175define signext i8 @sext_i1_i8(i1 %a) nounwind ssp {176entry:177; CHECK-LABEL: sext_i1_i8178; CHECK: sbfx [[REG:w[0-9]+]], w0, #0, #1179; CHECK: sxtb w0, [[REG]]180 %conv = sext i1 %a to i8181 ret i8 %conv182}183 184; Test fpext185define double @fpext_(float %a) nounwind ssp {186entry:187; CHECK-LABEL: fpext_188; CHECK: fcvt d0, s0189 %conv = fpext float %a to double190 ret double %conv191}192 193; Test fptrunc194define float @fptrunc_(double %a) nounwind ssp {195entry:196; CHECK-LABEL: fptrunc_197; CHECK: fcvt s0, d0198 %conv = fptrunc double %a to float199 ret float %conv200}201 202; Test fptosi203define i32 @fptosi_ws(float %a) nounwind ssp {204entry:205; CHECK-LABEL: fptosi_ws206; CHECK: fcvtzs w0, s0207 %conv = fptosi float %a to i32208 ret i32 %conv209}210 211; Test fptosi212define i32 @fptosi_wd(double %a) nounwind ssp {213entry:214; CHECK-LABEL: fptosi_wd215; CHECK: fcvtzs w0, d0216 %conv = fptosi double %a to i32217 ret i32 %conv218}219 220; Test fptoui221define i32 @fptoui_ws(float %a) nounwind ssp {222entry:223; CHECK-LABEL: fptoui_ws224; CHECK: fcvtzu w0, s0225 %conv = fptoui float %a to i32226 ret i32 %conv227}228 229; Test fptoui230define i32 @fptoui_wd(double %a) nounwind ssp {231entry:232; CHECK-LABEL: fptoui_wd233; CHECK: fcvtzu w0, d0234 %conv = fptoui double %a to i32235 ret i32 %conv236}237 238; Test sitofp239define float @sitofp_sw_i1(i1 %a) nounwind ssp {240entry:241; CHECK-LABEL: sitofp_sw_i1242; CHECK: sbfx [[REG:w[0-9]+]], w0, #0, #1243; CHECK: scvtf s0, [[REG]]244 %conv = sitofp i1 %a to float245 ret float %conv246}247 248; Test sitofp249define float @sitofp_sw_i8(i8 %a) nounwind ssp {250entry:251; CHECK-LABEL: sitofp_sw_i8252; CHECK: sxtb [[REG:w[0-9]+]], w0253; CHECK: scvtf s0, [[REG]]254 %conv = sitofp i8 %a to float255 ret float %conv256}257 258; Test sitofp259define float @sitofp_sw_i16(i16 %a) nounwind ssp {260entry:261; CHECK-LABEL: sitofp_sw_i16262 %conv = sitofp i16 %a to float263 ret float %conv264}265 266; Test sitofp267define float @sitofp_sw(i32 %a) nounwind ssp {268entry:269; CHECK-LABEL: sitofp_sw270; CHECK: scvtf s0, w0271 %conv = sitofp i32 %a to float272 ret float %conv273}274 275; Test sitofp276define float @sitofp_sx(i64 %a) nounwind ssp {277entry:278; CHECK-LABEL: sitofp_sx279; CHECK: scvtf s0, x0280 %conv = sitofp i64 %a to float281 ret float %conv282}283 284; Test sitofp285define double @sitofp_dw(i32 %a) nounwind ssp {286entry:287; CHECK-LABEL: sitofp_dw288; CHECK: scvtf d0, w0289 %conv = sitofp i32 %a to double290 ret double %conv291}292 293; Test sitofp294define double @sitofp_dx(i64 %a) nounwind ssp {295entry:296; CHECK-LABEL: sitofp_dx297; CHECK: scvtf d0, x0298 %conv = sitofp i64 %a to double299 ret double %conv300}301 302; Test uitofp303define float @uitofp_sw_i1(i1 %a) nounwind ssp {304entry:305; CHECK-LABEL: uitofp_sw_i1306; CHECK: and [[REG:w[0-9]+]], w0, #0x1307; CHECK: ucvtf s0, [[REG]]308 %conv = uitofp i1 %a to float309 ret float %conv310}311 312; Test uitofp313define float @uitofp_sw_i8(i8 %a) nounwind ssp {314entry:315; CHECK-LABEL: uitofp_sw_i8316 %conv = uitofp i8 %a to float317 ret float %conv318}319 320; Test uitofp321define float @uitofp_sw_i16(i16 %a) nounwind ssp {322entry:323; CHECK-LABEL: uitofp_sw_i16324 %conv = uitofp i16 %a to float325 ret float %conv326}327 328; Test uitofp329define float @uitofp_sw(i32 %a) nounwind ssp {330entry:331; CHECK-LABEL: uitofp_sw332; CHECK: ucvtf s0, w0333 %conv = uitofp i32 %a to float334 ret float %conv335}336 337; Test uitofp338define float @uitofp_sx(i64 %a) nounwind ssp {339entry:340; CHECK-LABEL: uitofp_sx341; CHECK: ucvtf s0, x0342 %conv = uitofp i64 %a to float343 ret float %conv344}345 346; Test uitofp347define double @uitofp_dw(i32 %a) nounwind ssp {348entry:349; CHECK-LABEL: uitofp_dw350; CHECK: ucvtf d0, w0351 %conv = uitofp i32 %a to double352 ret double %conv353}354 355; Test uitofp356define double @uitofp_dx(i64 %a) nounwind ssp {357entry:358; CHECK-LABEL: uitofp_dx359; CHECK: ucvtf d0, x0360 %conv = uitofp i64 %a to double361 ret double %conv362}363 364define i32 @i64_trunc_i32(i64 %a) nounwind ssp {365entry:366; CHECK-LABEL: i64_trunc_i32367; CHECK-NOT: mov368; CHECK: ret369 %conv = trunc i64 %a to i32370 ret i32 %conv371}372 373define zeroext i16 @i64_trunc_i16(i64 %a) nounwind ssp {374entry:375; CHECK-LABEL: i64_trunc_i16376; CHECK: mov x[[TMP:[0-9]+]], x0377; CHECK: and [[REG2:w[0-9]+]], w[[TMP]], #0xffff{{$}}378; CHECK: uxth w0, [[REG2]]379 %conv = trunc i64 %a to i16380 ret i16 %conv381}382 383define zeroext i8 @i64_trunc_i8(i64 %a) nounwind ssp {384entry:385; CHECK-LABEL: i64_trunc_i8386; CHECK: mov x[[TMP:[0-9]+]], x0387; CHECK: and [[REG2:w[0-9]+]], w[[TMP]], #0xff{{$}}388; CHECK: uxtb w0, [[REG2]]389 %conv = trunc i64 %a to i8390 ret i8 %conv391}392 393define zeroext i1 @i64_trunc_i1(i64 %a) nounwind ssp {394entry:395; CHECK-LABEL: i64_trunc_i1396; CHECK: mov x[[TMP:[0-9]+]], x0397; CHECK: and [[REG2:w[0-9]+]], w[[TMP]], #0x1{{$}}398; CHECK: and w0, [[REG2]], #0x1399 %conv = trunc i64 %a to i1400 ret i1 %conv401}402 403; rdar://15101939404define void @stack_trunc() nounwind {405; CHECK-LABEL: stack_trunc406; CHECK: sub sp, sp, #16407; CHECK: ldr x[[REG:[0-9]+]], [sp]408; CHECK: and [[REG3:w[0-9]+]], w[[REG]], #0xff409; CHECK: strb [[REG3]], [sp, #15]410; CHECK: add sp, sp, #16411 %a = alloca i8, align 1412 %b = alloca i64, align 8413 %c = load i64, ptr %b, align 8414 %d = trunc i64 %c to i8415 store i8 %d, ptr %a, align 1416 ret void417}418 419define zeroext i64 @zext_i8_i64(i8 zeroext %in) {420; CHECK-LABEL: zext_i8_i64:421; CHECK-NOT: ubfx x0, {{x[0-9]+}}, #0, #8422; CHECK: ret423 %big = zext i8 %in to i64424 ret i64 %big425}426define zeroext i64 @zext_i16_i64(i16 zeroext %in) {427; CHECK-LABEL: zext_i16_i64:428; CHECK-NOT: ubfx x0, {{x[0-9]+}}, #0, #16429; CHECK: ret430 %big = zext i16 %in to i64431 ret i64 %big432}433 434define float @bitcast_i32_to_float(i32 %a) {435 %1 = bitcast i32 %a to float436 ret float %1437}438 439define double @bitcast_i64_to_double(i64 %a) {440 %1 = bitcast i64 %a to double441 ret double %1442}443 444define i32 @bitcast_float_to_i32(float %a) {445 %1 = bitcast float %a to i32446 ret i32 %1447}448 449define i64 @bitcast_double_to_i64(double %a) {450 %1 = bitcast double %a to i64451 ret i64 %1452}453 454