290 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc -mtriple=aarch64-linux-gnu -o - %s | FileCheck %s3 4; This file tests eliding stack slots when lowering the FSINCOS ISD node.5 6define { float, float } @sincos_f32_value_return(float %x) {7; CHECK-LABEL: sincos_f32_value_return:8; CHECK: // %bb.0: // %entry9; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill10; CHECK-NEXT: .cfi_def_cfa_offset 1611; CHECK-NEXT: .cfi_offset w30, -1612; CHECK-NEXT: add x0, sp, #1213; CHECK-NEXT: add x1, sp, #814; CHECK-NEXT: bl sincosf15; CHECK-NEXT: ldp s1, s0, [sp, #8]16; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload17; CHECK-NEXT: ret18entry:19 %sin = tail call float @llvm.sin.f32(float %x)20 %cos = tail call float @llvm.cos.f32(float %x)21 %ret_0 = insertvalue { float, float } poison, float %sin, 022 %ret_1 = insertvalue { float, float } %ret_0, float %cos, 123 ret { float, float } %ret_124}25 26define void @sincos_f32_ptr_return(float %x, ptr noalias %out_sin, ptr noalias %out_cos) {27; CHECK-LABEL: sincos_f32_ptr_return:28; CHECK: // %bb.0: // %entry29; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill30; CHECK-NEXT: .cfi_def_cfa_offset 1631; CHECK-NEXT: .cfi_offset w30, -1632; CHECK-NEXT: bl sincosf33; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload34; CHECK-NEXT: ret35entry:36 %sin = tail call float @llvm.sin.f32(float %x)37 %cos = tail call float @llvm.cos.f32(float %x)38 store float %sin, ptr %out_sin, align 439 store float %cos, ptr %out_cos, align 440 ret void41}42 43define float @sincos_f32_mixed_return(float %x, ptr %out_sin) {44; CHECK-LABEL: sincos_f32_mixed_return:45; CHECK: // %bb.0: // %entry46; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill47; CHECK-NEXT: .cfi_def_cfa_offset 1648; CHECK-NEXT: .cfi_offset w30, -1649; CHECK-NEXT: add x1, sp, #1250; CHECK-NEXT: bl sincosf51; CHECK-NEXT: ldr s0, [sp, #12]52; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload53; CHECK-NEXT: ret54entry:55 %sin = tail call float @llvm.sin.f32(float %x)56 %cos = tail call float @llvm.cos.f32(float %x)57 store float %sin, ptr %out_sin, align 458 ret float %cos59}60 61define { double, double } @sincos_f64_value_return(double %x) {62; CHECK-LABEL: sincos_f64_value_return:63; CHECK: // %bb.0: // %entry64; CHECK-NEXT: sub sp, sp, #3265; CHECK-NEXT: str x30, [sp, #16] // 8-byte Spill66; CHECK-NEXT: .cfi_def_cfa_offset 3267; CHECK-NEXT: .cfi_offset w30, -1668; CHECK-NEXT: add x0, sp, #2469; CHECK-NEXT: add x1, sp, #870; CHECK-NEXT: bl sincos71; CHECK-NEXT: ldr d0, [sp, #24]72; CHECK-NEXT: ldr d1, [sp, #8]73; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Reload74; CHECK-NEXT: add sp, sp, #3275; CHECK-NEXT: ret76entry:77 %sin = tail call double @llvm.sin.f64(double %x)78 %cos = tail call double @llvm.cos.f64(double %x)79 %ret_0 = insertvalue { double, double } poison, double %sin, 080 %ret_1 = insertvalue { double, double } %ret_0, double %cos, 181 ret { double, double } %ret_182}83 84define void @sincos_f64_ptr_return(double %x, ptr noalias %out_sin, ptr noalias %out_cos) {85; CHECK-LABEL: sincos_f64_ptr_return:86; CHECK: // %bb.0: // %entry87; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill88; CHECK-NEXT: .cfi_def_cfa_offset 1689; CHECK-NEXT: .cfi_offset w30, -1690; CHECK-NEXT: bl sincos91; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload92; CHECK-NEXT: ret93entry:94 %sin = tail call double @llvm.sin.f64(double %x)95 %cos = tail call double @llvm.cos.f64(double %x)96 store double %sin, ptr %out_sin, align 897 store double %cos, ptr %out_cos, align 898 ret void99}100 101define double @sincos_f64_mixed_return(double %x, ptr %out_sin) {102; CHECK-LABEL: sincos_f64_mixed_return:103; CHECK: // %bb.0: // %entry104; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill105; CHECK-NEXT: .cfi_def_cfa_offset 16106; CHECK-NEXT: .cfi_offset w30, -16107; CHECK-NEXT: add x1, sp, #8108; CHECK-NEXT: bl sincos109; CHECK-NEXT: ldr d0, [sp, #8]110; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload111; CHECK-NEXT: ret112entry:113 %sin = tail call double @llvm.sin.f64(double %x)114 %cos = tail call double @llvm.cos.f64(double %x)115 store double %sin, ptr %out_sin, align 8116 ret double %cos117}118 119; Here %out_sin and %out_cos may alias so we can't replace both stores with the120; call to sincosf (as the order of stores in sincosf is not defined).121define void @sincos_may_alias(float %x, ptr %out_sin, ptr %out_cos) {122; CHECK-LABEL: sincos_may_alias:123; CHECK: // %bb.0: // %entry124; CHECK-NEXT: sub sp, sp, #32125; CHECK-NEXT: stp x30, x19, [sp, #16] // 16-byte Folded Spill126; CHECK-NEXT: .cfi_def_cfa_offset 32127; CHECK-NEXT: .cfi_offset w19, -8128; CHECK-NEXT: .cfi_offset w30, -16129; CHECK-NEXT: mov x19, x1130; CHECK-NEXT: add x1, sp, #12131; CHECK-NEXT: bl sincosf132; CHECK-NEXT: ldr s0, [sp, #12]133; CHECK-NEXT: str s0, [x19]134; CHECK-NEXT: ldp x30, x19, [sp, #16] // 16-byte Folded Reload135; CHECK-NEXT: add sp, sp, #32136; CHECK-NEXT: ret137entry:138 %sin = tail call float @llvm.sin.f32(float %x)139 %cos = tail call float @llvm.cos.f32(float %x)140 store float %sin, ptr %out_sin, align 4141 store float %cos, ptr %out_cos, align 4142 ret void143}144 145; Here %out is used for both sin and cos (with the final value stored being cos).146define float @sincos_multiple_uses(float %x, ptr %out) {147; CHECK-LABEL: sincos_multiple_uses:148; CHECK: // %bb.0:149; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill150; CHECK-NEXT: .cfi_def_cfa_offset 16151; CHECK-NEXT: .cfi_offset w30, -16152; CHECK-NEXT: mov x1, x0153; CHECK-NEXT: add x0, sp, #12154; CHECK-NEXT: bl sincosf155; CHECK-NEXT: ldr s0, [sp, #12]156; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload157; CHECK-NEXT: ret158 %sin = call float @llvm.sin.f32(float %x)159 store float %sin, ptr %out, align 4160 %reload = load float, ptr %out, align 4161 %cos = call float @llvm.cos.f32(float %x)162 store float %cos, ptr %out, align 4163 ret float %reload164}165 166; Negative test. We can't fold volatile stores into the library call.167define void @sincos_volatile_result_stores(float %x, ptr noalias %out_sin, ptr noalias %out_cos) {168; CHECK-LABEL: sincos_volatile_result_stores:169; CHECK: // %bb.0: // %entry170; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill171; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill172; CHECK-NEXT: .cfi_def_cfa_offset 32173; CHECK-NEXT: .cfi_offset w19, -8174; CHECK-NEXT: .cfi_offset w20, -16175; CHECK-NEXT: .cfi_offset w30, -32176; CHECK-NEXT: mov x19, x1177; CHECK-NEXT: mov x20, x0178; CHECK-NEXT: add x0, sp, #12179; CHECK-NEXT: add x1, sp, #8180; CHECK-NEXT: bl sincosf181; CHECK-NEXT: ldp s1, s0, [sp, #8]182; CHECK-NEXT: str s0, [x20]183; CHECK-NEXT: str s1, [x19]184; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload185; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload186; CHECK-NEXT: ret187entry:188 %sin = tail call float @llvm.sin.f32(float %x)189 %cos = tail call float @llvm.cos.f32(float %x)190 store volatile float %sin, ptr %out_sin, align 4191 store volatile float %cos, ptr %out_cos, align 4192 ret void193}194 195; Negative test. We can't fold atomic stores into the library call.196define void @sincos_atomic_result_stores(float %x, ptr noalias %out_sin, ptr noalias %out_cos) {197; CHECK-LABEL: sincos_atomic_result_stores:198; CHECK: // %bb.0: // %entry199; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill200; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill201; CHECK-NEXT: .cfi_def_cfa_offset 32202; CHECK-NEXT: .cfi_offset w19, -8203; CHECK-NEXT: .cfi_offset w20, -16204; CHECK-NEXT: .cfi_offset w30, -32205; CHECK-NEXT: mov x19, x1206; CHECK-NEXT: mov x20, x0207; CHECK-NEXT: add x0, sp, #12208; CHECK-NEXT: add x1, sp, #8209; CHECK-NEXT: bl sincosf210; CHECK-NEXT: ldr w8, [sp, #12]211; CHECK-NEXT: str w8, [x20]212; CHECK-NEXT: ldr w8, [sp, #8]213; CHECK-NEXT: str w8, [x19]214; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload215; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload216; CHECK-NEXT: ret217entry:218 %sin = tail call float @llvm.sin.f32(float %x)219 %cos = tail call float @llvm.cos.f32(float %x)220 store atomic float %sin, ptr %out_sin unordered, align 4221 store atomic float %cos, ptr %out_cos unordered, align 4222 ret void223}224 225; Negative test. We can't fold misaligned stores into the library call.226define void @sincos_misaligned_result_stores(double %x, ptr noalias %out_sin, ptr noalias %out_cos) {227; CHECK-LABEL: sincos_misaligned_result_stores:228; CHECK: // %bb.0: // %entry229; CHECK-NEXT: sub sp, sp, #48230; CHECK-NEXT: str x30, [sp, #16] // 8-byte Spill231; CHECK-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill232; CHECK-NEXT: .cfi_def_cfa_offset 48233; CHECK-NEXT: .cfi_offset w19, -8234; CHECK-NEXT: .cfi_offset w20, -16235; CHECK-NEXT: .cfi_offset w30, -32236; CHECK-NEXT: mov x19, x1237; CHECK-NEXT: mov x20, x0238; CHECK-NEXT: add x0, sp, #24239; CHECK-NEXT: add x1, sp, #8240; CHECK-NEXT: bl sincos241; CHECK-NEXT: ldr d0, [sp, #24]242; CHECK-NEXT: ldr d1, [sp, #8]243; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Reload244; CHECK-NEXT: str d0, [x20]245; CHECK-NEXT: str d1, [x19]246; CHECK-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload247; CHECK-NEXT: add sp, sp, #48248; CHECK-NEXT: ret249entry:250 %sin = tail call double @llvm.sin.f64(double %x)251 %cos = tail call double @llvm.cos.f64(double %x)252 store double %sin, ptr %out_sin, align 4253 store double %cos, ptr %out_cos, align 4254 ret void255}256 257declare void @foo(ptr, ptr)258 259define void @can_fold_with_call_in_chain(float %x, ptr noalias %a, ptr noalias %b) {260; CHECK-LABEL: can_fold_with_call_in_chain:261; CHECK: // %bb.0: // %entry262; CHECK-NEXT: str d8, [sp, #-32]! // 8-byte Folded Spill263; CHECK-NEXT: str x30, [sp, #8] // 8-byte Spill264; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill265; CHECK-NEXT: .cfi_def_cfa_offset 32266; CHECK-NEXT: .cfi_offset w19, -8267; CHECK-NEXT: .cfi_offset w20, -16268; CHECK-NEXT: .cfi_offset w30, -24269; CHECK-NEXT: .cfi_offset b8, -32270; CHECK-NEXT: mov x19, x1271; CHECK-NEXT: mov x20, x0272; CHECK-NEXT: fmov s8, s0273; CHECK-NEXT: bl foo274; CHECK-NEXT: fmov s0, s8275; CHECK-NEXT: mov x0, x20276; CHECK-NEXT: mov x1, x19277; CHECK-NEXT: bl sincosf278; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload279; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Reload280; CHECK-NEXT: ldr d8, [sp], #32 // 8-byte Folded Reload281; CHECK-NEXT: ret282entry:283 %sin = tail call float @llvm.sin.f32(float %x)284 %cos = tail call float @llvm.cos.f32(float %x)285 call void @foo(ptr %a, ptr %b)286 store float %sin, ptr %a, align 4287 store float %cos, ptr %b, align 4288 ret void289}290