819 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \3; RUN: | FileCheck %s -check-prefix=RV32I4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \5; RUN: | FileCheck %s -check-prefix=RV64I6; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f \7; RUN: -target-abi ilp32f < %s | FileCheck %s -check-prefix=RV32IF8; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f -mattr=+d \9; RUN: -target-abi ilp32d < %s | FileCheck %s -check-prefix=RV32IFD10; RUN: llc -mtriple=riscv64 -verify-machineinstrs -mattr=+f -mattr=+d \11; RUN: -target-abi lp64d < %s | FileCheck %s -check-prefix=RV64IFD12; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f \13; RUN: -mattr=+zfh -target-abi ilp32f < %s \14; RUN: | FileCheck %s -check-prefix=RV32IFZFH15; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f -mattr=+d \16; RUN: -mattr=+zfh -target-abi ilp32d < %s \17; RUN: | FileCheck %s -check-prefix=RV32IFDZFH18; RUN: llc -mtriple=riscv64 -verify-machineinstrs -mattr=+f -mattr=+d \19; RUN: -mattr=+zfh -target-abi lp64d < %s \20; RUN: | FileCheck %s -check-prefix=RV64IFDZFH21; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f \22; RUN: -mattr=+zfhmin -target-abi ilp32f < %s \23; RUN: | FileCheck %s -check-prefix=RV32IFZFHMIN24; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f -mattr=+d \25; RUN: -mattr=+zfhmin -target-abi ilp32d < %s \26; RUN: | FileCheck %s -check-prefix=RV32IFDZFHMIN27; RUN: llc -mtriple=riscv64 -verify-machineinstrs -mattr=+f -mattr=+d \28; RUN: -mattr=+zfhmin -target-abi lp64d < %s \29; RUN: | FileCheck %s -check-prefix=RV64IFDZFHMIN30; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+zdinx \31; RUN: -target-abi ilp32 < %s \32; RUN: | FileCheck %s -check-prefix=RV32IZDINX33; RUN: llc -mtriple=riscv64 -verify-machineinstrs -mattr=+zdinx \34; RUN: -target-abi lp64 < %s \35; RUN: | FileCheck %s -check-prefix=RV64IZDINX36 37; Test fcopysign scenarios where the sign argument is casted to the type of the38; magnitude argument. Those casts can be folded away by the DAGCombiner.39 40define double @fold_promote_d_s(double %a, float %b) nounwind {41; RV32I-LABEL: fold_promote_d_s:42; RV32I: # %bb.0:43; RV32I-NEXT: lui a3, 52428844; RV32I-NEXT: slli a1, a1, 145; RV32I-NEXT: and a2, a2, a346; RV32I-NEXT: srli a1, a1, 147; RV32I-NEXT: or a1, a1, a248; RV32I-NEXT: ret49;50; RV64I-LABEL: fold_promote_d_s:51; RV64I: # %bb.0:52; RV64I-NEXT: lui a2, 52428853; RV64I-NEXT: slli a0, a0, 154; RV64I-NEXT: and a1, a1, a255; RV64I-NEXT: slli a1, a1, 3256; RV64I-NEXT: srli a0, a0, 157; RV64I-NEXT: or a0, a0, a158; RV64I-NEXT: ret59;60; RV32IF-LABEL: fold_promote_d_s:61; RV32IF: # %bb.0:62; RV32IF-NEXT: fmv.x.w a2, fa063; RV32IF-NEXT: lui a3, 52428864; RV32IF-NEXT: slli a1, a1, 165; RV32IF-NEXT: and a2, a2, a366; RV32IF-NEXT: srli a1, a1, 167; RV32IF-NEXT: or a1, a1, a268; RV32IF-NEXT: ret69;70; RV32IFD-LABEL: fold_promote_d_s:71; RV32IFD: # %bb.0:72; RV32IFD-NEXT: fcvt.d.s fa5, fa173; RV32IFD-NEXT: fsgnj.d fa0, fa0, fa574; RV32IFD-NEXT: ret75;76; RV64IFD-LABEL: fold_promote_d_s:77; RV64IFD: # %bb.0:78; RV64IFD-NEXT: fcvt.d.s fa5, fa179; RV64IFD-NEXT: fsgnj.d fa0, fa0, fa580; RV64IFD-NEXT: ret81;82; RV32IFZFH-LABEL: fold_promote_d_s:83; RV32IFZFH: # %bb.0:84; RV32IFZFH-NEXT: fmv.x.w a2, fa085; RV32IFZFH-NEXT: lui a3, 52428886; RV32IFZFH-NEXT: slli a1, a1, 187; RV32IFZFH-NEXT: and a2, a2, a388; RV32IFZFH-NEXT: srli a1, a1, 189; RV32IFZFH-NEXT: or a1, a1, a290; RV32IFZFH-NEXT: ret91;92; RV32IFDZFH-LABEL: fold_promote_d_s:93; RV32IFDZFH: # %bb.0:94; RV32IFDZFH-NEXT: fcvt.d.s fa5, fa195; RV32IFDZFH-NEXT: fsgnj.d fa0, fa0, fa596; RV32IFDZFH-NEXT: ret97;98; RV64IFDZFH-LABEL: fold_promote_d_s:99; RV64IFDZFH: # %bb.0:100; RV64IFDZFH-NEXT: fcvt.d.s fa5, fa1101; RV64IFDZFH-NEXT: fsgnj.d fa0, fa0, fa5102; RV64IFDZFH-NEXT: ret103;104; RV32IFZFHMIN-LABEL: fold_promote_d_s:105; RV32IFZFHMIN: # %bb.0:106; RV32IFZFHMIN-NEXT: fmv.x.w a2, fa0107; RV32IFZFHMIN-NEXT: lui a3, 524288108; RV32IFZFHMIN-NEXT: slli a1, a1, 1109; RV32IFZFHMIN-NEXT: and a2, a2, a3110; RV32IFZFHMIN-NEXT: srli a1, a1, 1111; RV32IFZFHMIN-NEXT: or a1, a1, a2112; RV32IFZFHMIN-NEXT: ret113;114; RV32IFDZFHMIN-LABEL: fold_promote_d_s:115; RV32IFDZFHMIN: # %bb.0:116; RV32IFDZFHMIN-NEXT: fcvt.d.s fa5, fa1117; RV32IFDZFHMIN-NEXT: fsgnj.d fa0, fa0, fa5118; RV32IFDZFHMIN-NEXT: ret119;120; RV64IFDZFHMIN-LABEL: fold_promote_d_s:121; RV64IFDZFHMIN: # %bb.0:122; RV64IFDZFHMIN-NEXT: fcvt.d.s fa5, fa1123; RV64IFDZFHMIN-NEXT: fsgnj.d fa0, fa0, fa5124; RV64IFDZFHMIN-NEXT: ret125;126; RV32IZDINX-LABEL: fold_promote_d_s:127; RV32IZDINX: # %bb.0:128; RV32IZDINX-NEXT: fcvt.d.s a2, a2129; RV32IZDINX-NEXT: fsgnj.d a0, a0, a2130; RV32IZDINX-NEXT: ret131;132; RV64IZDINX-LABEL: fold_promote_d_s:133; RV64IZDINX: # %bb.0:134; RV64IZDINX-NEXT: fcvt.d.s a1, a1135; RV64IZDINX-NEXT: fsgnj.d a0, a0, a1136; RV64IZDINX-NEXT: ret137 %c = fpext float %b to double138 %t = call double @llvm.copysign.f64(double %a, double %c)139 ret double %t140}141 142define double @fold_promote_d_h(double %a, half %b) nounwind {143; RV32I-LABEL: fold_promote_d_h:144; RV32I: # %bb.0:145; RV32I-NEXT: lui a3, 8146; RV32I-NEXT: slli a1, a1, 1147; RV32I-NEXT: and a2, a2, a3148; RV32I-NEXT: slli a2, a2, 16149; RV32I-NEXT: srli a1, a1, 1150; RV32I-NEXT: or a1, a1, a2151; RV32I-NEXT: ret152;153; RV64I-LABEL: fold_promote_d_h:154; RV64I: # %bb.0:155; RV64I-NEXT: lui a2, 8156; RV64I-NEXT: slli a0, a0, 1157; RV64I-NEXT: and a1, a1, a2158; RV64I-NEXT: slli a1, a1, 48159; RV64I-NEXT: srli a0, a0, 1160; RV64I-NEXT: or a0, a0, a1161; RV64I-NEXT: ret162;163; RV32IF-LABEL: fold_promote_d_h:164; RV32IF: # %bb.0:165; RV32IF-NEXT: fmv.x.w a2, fa0166; RV32IF-NEXT: lui a3, 8167; RV32IF-NEXT: slli a1, a1, 1168; RV32IF-NEXT: and a2, a2, a3169; RV32IF-NEXT: slli a2, a2, 16170; RV32IF-NEXT: srli a1, a1, 1171; RV32IF-NEXT: or a1, a1, a2172; RV32IF-NEXT: ret173;174; RV32IFD-LABEL: fold_promote_d_h:175; RV32IFD: # %bb.0:176; RV32IFD-NEXT: addi sp, sp, -16177; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill178; RV32IFD-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill179; RV32IFD-NEXT: fmv.d fs0, fa0180; RV32IFD-NEXT: fmv.s fa0, fa1181; RV32IFD-NEXT: call __extendhfsf2182; RV32IFD-NEXT: fcvt.d.s fa5, fa0183; RV32IFD-NEXT: fsgnj.d fa0, fs0, fa5184; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload185; RV32IFD-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload186; RV32IFD-NEXT: addi sp, sp, 16187; RV32IFD-NEXT: ret188;189; RV64IFD-LABEL: fold_promote_d_h:190; RV64IFD: # %bb.0:191; RV64IFD-NEXT: addi sp, sp, -16192; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill193; RV64IFD-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill194; RV64IFD-NEXT: fmv.d fs0, fa0195; RV64IFD-NEXT: fmv.s fa0, fa1196; RV64IFD-NEXT: call __extendhfsf2197; RV64IFD-NEXT: fcvt.d.s fa5, fa0198; RV64IFD-NEXT: fsgnj.d fa0, fs0, fa5199; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload200; RV64IFD-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload201; RV64IFD-NEXT: addi sp, sp, 16202; RV64IFD-NEXT: ret203;204; RV32IFZFH-LABEL: fold_promote_d_h:205; RV32IFZFH: # %bb.0:206; RV32IFZFH-NEXT: fmv.x.h a2, fa0207; RV32IFZFH-NEXT: lui a3, 8208; RV32IFZFH-NEXT: slli a1, a1, 1209; RV32IFZFH-NEXT: and a2, a2, a3210; RV32IFZFH-NEXT: slli a2, a2, 16211; RV32IFZFH-NEXT: srli a1, a1, 1212; RV32IFZFH-NEXT: or a1, a1, a2213; RV32IFZFH-NEXT: ret214;215; RV32IFDZFH-LABEL: fold_promote_d_h:216; RV32IFDZFH: # %bb.0:217; RV32IFDZFH-NEXT: fcvt.d.h fa5, fa1218; RV32IFDZFH-NEXT: fsgnj.d fa0, fa0, fa5219; RV32IFDZFH-NEXT: ret220;221; RV64IFDZFH-LABEL: fold_promote_d_h:222; RV64IFDZFH: # %bb.0:223; RV64IFDZFH-NEXT: fcvt.d.h fa5, fa1224; RV64IFDZFH-NEXT: fsgnj.d fa0, fa0, fa5225; RV64IFDZFH-NEXT: ret226;227; RV32IFZFHMIN-LABEL: fold_promote_d_h:228; RV32IFZFHMIN: # %bb.0:229; RV32IFZFHMIN-NEXT: fmv.x.h a2, fa0230; RV32IFZFHMIN-NEXT: lui a3, 8231; RV32IFZFHMIN-NEXT: slli a1, a1, 1232; RV32IFZFHMIN-NEXT: and a2, a2, a3233; RV32IFZFHMIN-NEXT: slli a2, a2, 16234; RV32IFZFHMIN-NEXT: srli a1, a1, 1235; RV32IFZFHMIN-NEXT: or a1, a1, a2236; RV32IFZFHMIN-NEXT: ret237;238; RV32IFDZFHMIN-LABEL: fold_promote_d_h:239; RV32IFDZFHMIN: # %bb.0:240; RV32IFDZFHMIN-NEXT: fcvt.d.h fa5, fa1241; RV32IFDZFHMIN-NEXT: fsgnj.d fa0, fa0, fa5242; RV32IFDZFHMIN-NEXT: ret243;244; RV64IFDZFHMIN-LABEL: fold_promote_d_h:245; RV64IFDZFHMIN: # %bb.0:246; RV64IFDZFHMIN-NEXT: fcvt.d.h fa5, fa1247; RV64IFDZFHMIN-NEXT: fsgnj.d fa0, fa0, fa5248; RV64IFDZFHMIN-NEXT: ret249;250; RV32IZDINX-LABEL: fold_promote_d_h:251; RV32IZDINX: # %bb.0:252; RV32IZDINX-NEXT: addi sp, sp, -16253; RV32IZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill254; RV32IZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill255; RV32IZDINX-NEXT: sw s1, 4(sp) # 4-byte Folded Spill256; RV32IZDINX-NEXT: mv s1, a1257; RV32IZDINX-NEXT: mv s0, a0258; RV32IZDINX-NEXT: mv a0, a2259; RV32IZDINX-NEXT: call __extendhfsf2260; RV32IZDINX-NEXT: fcvt.d.s a0, a0261; RV32IZDINX-NEXT: fsgnj.d a0, s0, a0262; RV32IZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload263; RV32IZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload264; RV32IZDINX-NEXT: lw s1, 4(sp) # 4-byte Folded Reload265; RV32IZDINX-NEXT: addi sp, sp, 16266; RV32IZDINX-NEXT: ret267;268; RV64IZDINX-LABEL: fold_promote_d_h:269; RV64IZDINX: # %bb.0:270; RV64IZDINX-NEXT: addi sp, sp, -16271; RV64IZDINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill272; RV64IZDINX-NEXT: sd s0, 0(sp) # 8-byte Folded Spill273; RV64IZDINX-NEXT: mv s0, a0274; RV64IZDINX-NEXT: mv a0, a1275; RV64IZDINX-NEXT: call __extendhfsf2276; RV64IZDINX-NEXT: fcvt.d.s a0, a0277; RV64IZDINX-NEXT: fsgnj.d a0, s0, a0278; RV64IZDINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload279; RV64IZDINX-NEXT: ld s0, 0(sp) # 8-byte Folded Reload280; RV64IZDINX-NEXT: addi sp, sp, 16281; RV64IZDINX-NEXT: ret282 %c = fpext half %b to double283 %t = call double @llvm.copysign.f64(double %a, double %c)284 ret double %t285}286 287define float @fold_promote_f_h(float %a, half %b) nounwind {288; RV32I-LABEL: fold_promote_f_h:289; RV32I: # %bb.0:290; RV32I-NEXT: lui a2, 8291; RV32I-NEXT: slli a0, a0, 1292; RV32I-NEXT: and a1, a1, a2293; RV32I-NEXT: slli a1, a1, 16294; RV32I-NEXT: srli a0, a0, 1295; RV32I-NEXT: or a0, a0, a1296; RV32I-NEXT: ret297;298; RV64I-LABEL: fold_promote_f_h:299; RV64I: # %bb.0:300; RV64I-NEXT: lui a2, 8301; RV64I-NEXT: slli a0, a0, 33302; RV64I-NEXT: and a1, a1, a2303; RV64I-NEXT: slliw a1, a1, 16304; RV64I-NEXT: srli a0, a0, 33305; RV64I-NEXT: or a0, a0, a1306; RV64I-NEXT: ret307;308; RV32IF-LABEL: fold_promote_f_h:309; RV32IF: # %bb.0:310; RV32IF-NEXT: addi sp, sp, -16311; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill312; RV32IF-NEXT: fsw fs0, 8(sp) # 4-byte Folded Spill313; RV32IF-NEXT: fmv.s fs0, fa0314; RV32IF-NEXT: fmv.s fa0, fa1315; RV32IF-NEXT: call __extendhfsf2316; RV32IF-NEXT: fsgnj.s fa0, fs0, fa0317; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload318; RV32IF-NEXT: flw fs0, 8(sp) # 4-byte Folded Reload319; RV32IF-NEXT: addi sp, sp, 16320; RV32IF-NEXT: ret321;322; RV32IFD-LABEL: fold_promote_f_h:323; RV32IFD: # %bb.0:324; RV32IFD-NEXT: addi sp, sp, -16325; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill326; RV32IFD-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill327; RV32IFD-NEXT: fmv.s fs0, fa0328; RV32IFD-NEXT: fmv.s fa0, fa1329; RV32IFD-NEXT: call __extendhfsf2330; RV32IFD-NEXT: fsgnj.s fa0, fs0, fa0331; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload332; RV32IFD-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload333; RV32IFD-NEXT: addi sp, sp, 16334; RV32IFD-NEXT: ret335;336; RV64IFD-LABEL: fold_promote_f_h:337; RV64IFD: # %bb.0:338; RV64IFD-NEXT: addi sp, sp, -16339; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill340; RV64IFD-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill341; RV64IFD-NEXT: fmv.s fs0, fa0342; RV64IFD-NEXT: fmv.s fa0, fa1343; RV64IFD-NEXT: call __extendhfsf2344; RV64IFD-NEXT: fsgnj.s fa0, fs0, fa0345; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload346; RV64IFD-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload347; RV64IFD-NEXT: addi sp, sp, 16348; RV64IFD-NEXT: ret349;350; RV32IFZFH-LABEL: fold_promote_f_h:351; RV32IFZFH: # %bb.0:352; RV32IFZFH-NEXT: fcvt.s.h fa5, fa1353; RV32IFZFH-NEXT: fsgnj.s fa0, fa0, fa5354; RV32IFZFH-NEXT: ret355;356; RV32IFDZFH-LABEL: fold_promote_f_h:357; RV32IFDZFH: # %bb.0:358; RV32IFDZFH-NEXT: fcvt.s.h fa5, fa1359; RV32IFDZFH-NEXT: fsgnj.s fa0, fa0, fa5360; RV32IFDZFH-NEXT: ret361;362; RV64IFDZFH-LABEL: fold_promote_f_h:363; RV64IFDZFH: # %bb.0:364; RV64IFDZFH-NEXT: fcvt.s.h fa5, fa1365; RV64IFDZFH-NEXT: fsgnj.s fa0, fa0, fa5366; RV64IFDZFH-NEXT: ret367;368; RV32IFZFHMIN-LABEL: fold_promote_f_h:369; RV32IFZFHMIN: # %bb.0:370; RV32IFZFHMIN-NEXT: fcvt.s.h fa5, fa1371; RV32IFZFHMIN-NEXT: fsgnj.s fa0, fa0, fa5372; RV32IFZFHMIN-NEXT: ret373;374; RV32IFDZFHMIN-LABEL: fold_promote_f_h:375; RV32IFDZFHMIN: # %bb.0:376; RV32IFDZFHMIN-NEXT: fcvt.s.h fa5, fa1377; RV32IFDZFHMIN-NEXT: fsgnj.s fa0, fa0, fa5378; RV32IFDZFHMIN-NEXT: ret379;380; RV64IFDZFHMIN-LABEL: fold_promote_f_h:381; RV64IFDZFHMIN: # %bb.0:382; RV64IFDZFHMIN-NEXT: fcvt.s.h fa5, fa1383; RV64IFDZFHMIN-NEXT: fsgnj.s fa0, fa0, fa5384; RV64IFDZFHMIN-NEXT: ret385;386; RV32IZDINX-LABEL: fold_promote_f_h:387; RV32IZDINX: # %bb.0:388; RV32IZDINX-NEXT: addi sp, sp, -16389; RV32IZDINX-NEXT: sw ra, 12(sp) # 4-byte Folded Spill390; RV32IZDINX-NEXT: sw s0, 8(sp) # 4-byte Folded Spill391; RV32IZDINX-NEXT: mv s0, a0392; RV32IZDINX-NEXT: mv a0, a1393; RV32IZDINX-NEXT: call __extendhfsf2394; RV32IZDINX-NEXT: fsgnj.s a0, s0, a0395; RV32IZDINX-NEXT: lw ra, 12(sp) # 4-byte Folded Reload396; RV32IZDINX-NEXT: lw s0, 8(sp) # 4-byte Folded Reload397; RV32IZDINX-NEXT: addi sp, sp, 16398; RV32IZDINX-NEXT: ret399;400; RV64IZDINX-LABEL: fold_promote_f_h:401; RV64IZDINX: # %bb.0:402; RV64IZDINX-NEXT: addi sp, sp, -16403; RV64IZDINX-NEXT: sd ra, 8(sp) # 8-byte Folded Spill404; RV64IZDINX-NEXT: sd s0, 0(sp) # 8-byte Folded Spill405; RV64IZDINX-NEXT: mv s0, a0406; RV64IZDINX-NEXT: mv a0, a1407; RV64IZDINX-NEXT: call __extendhfsf2408; RV64IZDINX-NEXT: fsgnj.s a0, s0, a0409; RV64IZDINX-NEXT: ld ra, 8(sp) # 8-byte Folded Reload410; RV64IZDINX-NEXT: ld s0, 0(sp) # 8-byte Folded Reload411; RV64IZDINX-NEXT: addi sp, sp, 16412; RV64IZDINX-NEXT: ret413 %c = fpext half %b to float414 %t = call float @llvm.copysign.f32(float %a, float %c)415 ret float %t416}417 418define float @fold_demote_s_d(float %a, double %b) nounwind {419; RV32I-LABEL: fold_demote_s_d:420; RV32I: # %bb.0:421; RV32I-NEXT: lui a1, 524288422; RV32I-NEXT: slli a0, a0, 1423; RV32I-NEXT: and a1, a2, a1424; RV32I-NEXT: srli a0, a0, 1425; RV32I-NEXT: or a0, a0, a1426; RV32I-NEXT: ret427;428; RV64I-LABEL: fold_demote_s_d:429; RV64I: # %bb.0:430; RV64I-NEXT: slli a0, a0, 33431; RV64I-NEXT: srli a1, a1, 63432; RV64I-NEXT: srli a0, a0, 33433; RV64I-NEXT: slli a1, a1, 63434; RV64I-NEXT: srli a1, a1, 32435; RV64I-NEXT: or a0, a0, a1436; RV64I-NEXT: ret437;438; RV32IF-LABEL: fold_demote_s_d:439; RV32IF: # %bb.0:440; RV32IF-NEXT: fmv.w.x fa5, a1441; RV32IF-NEXT: fsgnj.s fa0, fa0, fa5442; RV32IF-NEXT: ret443;444; RV32IFD-LABEL: fold_demote_s_d:445; RV32IFD: # %bb.0:446; RV32IFD-NEXT: fcvt.s.d fa5, fa1447; RV32IFD-NEXT: fsgnj.s fa0, fa0, fa5448; RV32IFD-NEXT: ret449;450; RV64IFD-LABEL: fold_demote_s_d:451; RV64IFD: # %bb.0:452; RV64IFD-NEXT: fcvt.s.d fa5, fa1453; RV64IFD-NEXT: fsgnj.s fa0, fa0, fa5454; RV64IFD-NEXT: ret455;456; RV32IFZFH-LABEL: fold_demote_s_d:457; RV32IFZFH: # %bb.0:458; RV32IFZFH-NEXT: fmv.w.x fa5, a1459; RV32IFZFH-NEXT: fsgnj.s fa0, fa0, fa5460; RV32IFZFH-NEXT: ret461;462; RV32IFDZFH-LABEL: fold_demote_s_d:463; RV32IFDZFH: # %bb.0:464; RV32IFDZFH-NEXT: fcvt.s.d fa5, fa1465; RV32IFDZFH-NEXT: fsgnj.s fa0, fa0, fa5466; RV32IFDZFH-NEXT: ret467;468; RV64IFDZFH-LABEL: fold_demote_s_d:469; RV64IFDZFH: # %bb.0:470; RV64IFDZFH-NEXT: fcvt.s.d fa5, fa1471; RV64IFDZFH-NEXT: fsgnj.s fa0, fa0, fa5472; RV64IFDZFH-NEXT: ret473;474; RV32IFZFHMIN-LABEL: fold_demote_s_d:475; RV32IFZFHMIN: # %bb.0:476; RV32IFZFHMIN-NEXT: fmv.w.x fa5, a1477; RV32IFZFHMIN-NEXT: fsgnj.s fa0, fa0, fa5478; RV32IFZFHMIN-NEXT: ret479;480; RV32IFDZFHMIN-LABEL: fold_demote_s_d:481; RV32IFDZFHMIN: # %bb.0:482; RV32IFDZFHMIN-NEXT: fcvt.s.d fa5, fa1483; RV32IFDZFHMIN-NEXT: fsgnj.s fa0, fa0, fa5484; RV32IFDZFHMIN-NEXT: ret485;486; RV64IFDZFHMIN-LABEL: fold_demote_s_d:487; RV64IFDZFHMIN: # %bb.0:488; RV64IFDZFHMIN-NEXT: fcvt.s.d fa5, fa1489; RV64IFDZFHMIN-NEXT: fsgnj.s fa0, fa0, fa5490; RV64IFDZFHMIN-NEXT: ret491;492; RV32IZDINX-LABEL: fold_demote_s_d:493; RV32IZDINX: # %bb.0:494; RV32IZDINX-NEXT: mv a3, a2495; RV32IZDINX-NEXT: mv a2, a1496; RV32IZDINX-NEXT: fcvt.s.d a1, a2497; RV32IZDINX-NEXT: fsgnj.s a0, a0, a1498; RV32IZDINX-NEXT: ret499;500; RV64IZDINX-LABEL: fold_demote_s_d:501; RV64IZDINX: # %bb.0:502; RV64IZDINX-NEXT: fcvt.s.d a1, a1503; RV64IZDINX-NEXT: fsgnj.s a0, a0, a1504; RV64IZDINX-NEXT: ret505 %c = fptrunc double %b to float506 %t = call float @llvm.copysign.f32(float %a, float %c)507 ret float %t508}509 510define half @fold_demote_h_s(half %a, float %b) nounwind {511; RV32I-LABEL: fold_demote_h_s:512; RV32I: # %bb.0:513; RV32I-NEXT: lui a2, 524288514; RV32I-NEXT: slli a0, a0, 17515; RV32I-NEXT: and a1, a1, a2516; RV32I-NEXT: srli a1, a1, 16517; RV32I-NEXT: srli a0, a0, 17518; RV32I-NEXT: or a0, a0, a1519; RV32I-NEXT: ret520;521; RV64I-LABEL: fold_demote_h_s:522; RV64I: # %bb.0:523; RV64I-NEXT: srliw a1, a1, 31524; RV64I-NEXT: slli a0, a0, 49525; RV64I-NEXT: slli a1, a1, 15526; RV64I-NEXT: srli a0, a0, 49527; RV64I-NEXT: or a0, a0, a1528; RV64I-NEXT: ret529;530; RV32IF-LABEL: fold_demote_h_s:531; RV32IF: # %bb.0:532; RV32IF-NEXT: fmv.x.w a0, fa0533; RV32IF-NEXT: fmv.x.w a1, fa1534; RV32IF-NEXT: lui a2, 524288535; RV32IF-NEXT: and a1, a1, a2536; RV32IF-NEXT: slli a0, a0, 17537; RV32IF-NEXT: srli a1, a1, 16538; RV32IF-NEXT: srli a0, a0, 17539; RV32IF-NEXT: or a0, a0, a1540; RV32IF-NEXT: lui a1, 1048560541; RV32IF-NEXT: or a0, a0, a1542; RV32IF-NEXT: fmv.w.x fa0, a0543; RV32IF-NEXT: ret544;545; RV32IFD-LABEL: fold_demote_h_s:546; RV32IFD: # %bb.0:547; RV32IFD-NEXT: fmv.x.w a0, fa0548; RV32IFD-NEXT: fmv.x.w a1, fa1549; RV32IFD-NEXT: lui a2, 524288550; RV32IFD-NEXT: and a1, a1, a2551; RV32IFD-NEXT: slli a0, a0, 17552; RV32IFD-NEXT: srli a1, a1, 16553; RV32IFD-NEXT: srli a0, a0, 17554; RV32IFD-NEXT: or a0, a0, a1555; RV32IFD-NEXT: lui a1, 1048560556; RV32IFD-NEXT: or a0, a0, a1557; RV32IFD-NEXT: fmv.w.x fa0, a0558; RV32IFD-NEXT: ret559;560; RV64IFD-LABEL: fold_demote_h_s:561; RV64IFD: # %bb.0:562; RV64IFD-NEXT: fmv.x.w a0, fa0563; RV64IFD-NEXT: fmv.x.w a1, fa1564; RV64IFD-NEXT: lui a2, 524288565; RV64IFD-NEXT: and a1, a1, a2566; RV64IFD-NEXT: slli a0, a0, 49567; RV64IFD-NEXT: srli a1, a1, 16568; RV64IFD-NEXT: srli a0, a0, 49569; RV64IFD-NEXT: or a0, a0, a1570; RV64IFD-NEXT: lui a1, 1048560571; RV64IFD-NEXT: or a0, a0, a1572; RV64IFD-NEXT: fmv.w.x fa0, a0573; RV64IFD-NEXT: ret574;575; RV32IFZFH-LABEL: fold_demote_h_s:576; RV32IFZFH: # %bb.0:577; RV32IFZFH-NEXT: fcvt.h.s fa5, fa1578; RV32IFZFH-NEXT: fsgnj.h fa0, fa0, fa5579; RV32IFZFH-NEXT: ret580;581; RV32IFDZFH-LABEL: fold_demote_h_s:582; RV32IFDZFH: # %bb.0:583; RV32IFDZFH-NEXT: fcvt.h.s fa5, fa1584; RV32IFDZFH-NEXT: fsgnj.h fa0, fa0, fa5585; RV32IFDZFH-NEXT: ret586;587; RV64IFDZFH-LABEL: fold_demote_h_s:588; RV64IFDZFH: # %bb.0:589; RV64IFDZFH-NEXT: fcvt.h.s fa5, fa1590; RV64IFDZFH-NEXT: fsgnj.h fa0, fa0, fa5591; RV64IFDZFH-NEXT: ret592;593; RV32IFZFHMIN-LABEL: fold_demote_h_s:594; RV32IFZFHMIN: # %bb.0:595; RV32IFZFHMIN-NEXT: fmv.x.w a0, fa1596; RV32IFZFHMIN-NEXT: fmv.x.h a1, fa0597; RV32IFZFHMIN-NEXT: srli a0, a0, 31598; RV32IFZFHMIN-NEXT: slli a1, a1, 17599; RV32IFZFHMIN-NEXT: slli a0, a0, 15600; RV32IFZFHMIN-NEXT: srli a1, a1, 17601; RV32IFZFHMIN-NEXT: or a0, a1, a0602; RV32IFZFHMIN-NEXT: fmv.h.x fa0, a0603; RV32IFZFHMIN-NEXT: ret604;605; RV32IFDZFHMIN-LABEL: fold_demote_h_s:606; RV32IFDZFHMIN: # %bb.0:607; RV32IFDZFHMIN-NEXT: fmv.x.w a0, fa1608; RV32IFDZFHMIN-NEXT: fmv.x.h a1, fa0609; RV32IFDZFHMIN-NEXT: srli a0, a0, 31610; RV32IFDZFHMIN-NEXT: slli a1, a1, 17611; RV32IFDZFHMIN-NEXT: slli a0, a0, 15612; RV32IFDZFHMIN-NEXT: srli a1, a1, 17613; RV32IFDZFHMIN-NEXT: or a0, a1, a0614; RV32IFDZFHMIN-NEXT: fmv.h.x fa0, a0615; RV32IFDZFHMIN-NEXT: ret616;617; RV64IFDZFHMIN-LABEL: fold_demote_h_s:618; RV64IFDZFHMIN: # %bb.0:619; RV64IFDZFHMIN-NEXT: fmv.x.w a0, fa1620; RV64IFDZFHMIN-NEXT: fmv.x.h a1, fa0621; RV64IFDZFHMIN-NEXT: srli a0, a0, 31622; RV64IFDZFHMIN-NEXT: slli a1, a1, 49623; RV64IFDZFHMIN-NEXT: slli a0, a0, 15624; RV64IFDZFHMIN-NEXT: srli a1, a1, 49625; RV64IFDZFHMIN-NEXT: or a0, a1, a0626; RV64IFDZFHMIN-NEXT: fmv.h.x fa0, a0627; RV64IFDZFHMIN-NEXT: ret628;629; RV32IZDINX-LABEL: fold_demote_h_s:630; RV32IZDINX: # %bb.0:631; RV32IZDINX-NEXT: # kill: def $x11_w killed $x11_w def $x11632; RV32IZDINX-NEXT: # kill: def $x10_w killed $x10_w def $x10633; RV32IZDINX-NEXT: lui a2, 524288634; RV32IZDINX-NEXT: slli a0, a0, 17635; RV32IZDINX-NEXT: and a1, a1, a2636; RV32IZDINX-NEXT: lui a2, 1048560637; RV32IZDINX-NEXT: srli a0, a0, 17638; RV32IZDINX-NEXT: srli a1, a1, 16639; RV32IZDINX-NEXT: or a0, a0, a2640; RV32IZDINX-NEXT: or a0, a0, a1641; RV32IZDINX-NEXT: # kill: def $x10_w killed $x10_w killed $x10642; RV32IZDINX-NEXT: ret643;644; RV64IZDINX-LABEL: fold_demote_h_s:645; RV64IZDINX: # %bb.0:646; RV64IZDINX-NEXT: # kill: def $x11_w killed $x11_w def $x11647; RV64IZDINX-NEXT: # kill: def $x10_w killed $x10_w def $x10648; RV64IZDINX-NEXT: lui a2, 524288649; RV64IZDINX-NEXT: slli a0, a0, 49650; RV64IZDINX-NEXT: and a1, a1, a2651; RV64IZDINX-NEXT: lui a2, 1048560652; RV64IZDINX-NEXT: srli a0, a0, 49653; RV64IZDINX-NEXT: srli a1, a1, 16654; RV64IZDINX-NEXT: or a0, a0, a2655; RV64IZDINX-NEXT: or a0, a0, a1656; RV64IZDINX-NEXT: # kill: def $x10_w killed $x10_w killed $x10657; RV64IZDINX-NEXT: ret658 %c = fptrunc float %b to half659 %t = call half @llvm.copysign.f16(half %a, half %c)660 ret half %t661}662 663define half @fold_demote_h_d(half %a, double %b) nounwind {664; RV32I-LABEL: fold_demote_h_d:665; RV32I: # %bb.0:666; RV32I-NEXT: lui a1, 524288667; RV32I-NEXT: slli a0, a0, 17668; RV32I-NEXT: and a1, a2, a1669; RV32I-NEXT: srli a1, a1, 16670; RV32I-NEXT: srli a0, a0, 17671; RV32I-NEXT: or a0, a0, a1672; RV32I-NEXT: ret673;674; RV64I-LABEL: fold_demote_h_d:675; RV64I: # %bb.0:676; RV64I-NEXT: slli a0, a0, 49677; RV64I-NEXT: srli a1, a1, 63678; RV64I-NEXT: srli a0, a0, 49679; RV64I-NEXT: slli a1, a1, 63680; RV64I-NEXT: srli a1, a1, 48681; RV64I-NEXT: or a0, a0, a1682; RV64I-NEXT: ret683;684; RV32IF-LABEL: fold_demote_h_d:685; RV32IF: # %bb.0:686; RV32IF-NEXT: fmv.x.w a0, fa0687; RV32IF-NEXT: lui a2, 524288688; RV32IF-NEXT: and a1, a1, a2689; RV32IF-NEXT: slli a0, a0, 17690; RV32IF-NEXT: srli a1, a1, 16691; RV32IF-NEXT: srli a0, a0, 17692; RV32IF-NEXT: or a0, a0, a1693; RV32IF-NEXT: lui a1, 1048560694; RV32IF-NEXT: or a0, a0, a1695; RV32IF-NEXT: fmv.w.x fa0, a0696; RV32IF-NEXT: ret697;698; RV32IFD-LABEL: fold_demote_h_d:699; RV32IFD: # %bb.0:700; RV32IFD-NEXT: addi sp, sp, -16701; RV32IFD-NEXT: fsd fa1, 8(sp)702; RV32IFD-NEXT: lw a0, 12(sp)703; RV32IFD-NEXT: fmv.x.w a1, fa0704; RV32IFD-NEXT: lui a2, 524288705; RV32IFD-NEXT: and a0, a0, a2706; RV32IFD-NEXT: lui a2, 1048560707; RV32IFD-NEXT: slli a1, a1, 17708; RV32IFD-NEXT: srli a1, a1, 17709; RV32IFD-NEXT: srli a0, a0, 16710; RV32IFD-NEXT: or a1, a1, a2711; RV32IFD-NEXT: or a0, a1, a0712; RV32IFD-NEXT: fmv.w.x fa0, a0713; RV32IFD-NEXT: addi sp, sp, 16714; RV32IFD-NEXT: ret715;716; RV64IFD-LABEL: fold_demote_h_d:717; RV64IFD: # %bb.0:718; RV64IFD-NEXT: fmv.x.d a0, fa1719; RV64IFD-NEXT: fmv.x.w a1, fa0720; RV64IFD-NEXT: lui a2, 1048560721; RV64IFD-NEXT: slli a1, a1, 49722; RV64IFD-NEXT: srli a0, a0, 63723; RV64IFD-NEXT: srli a1, a1, 49724; RV64IFD-NEXT: slli a0, a0, 63725; RV64IFD-NEXT: srli a0, a0, 48726; RV64IFD-NEXT: or a1, a1, a2727; RV64IFD-NEXT: or a0, a1, a0728; RV64IFD-NEXT: fmv.w.x fa0, a0729; RV64IFD-NEXT: ret730;731; RV32IFZFH-LABEL: fold_demote_h_d:732; RV32IFZFH: # %bb.0:733; RV32IFZFH-NEXT: srli a1, a1, 16734; RV32IFZFH-NEXT: fmv.h.x fa5, a1735; RV32IFZFH-NEXT: fsgnj.h fa0, fa0, fa5736; RV32IFZFH-NEXT: ret737;738; RV32IFDZFH-LABEL: fold_demote_h_d:739; RV32IFDZFH: # %bb.0:740; RV32IFDZFH-NEXT: fcvt.h.d fa5, fa1741; RV32IFDZFH-NEXT: fsgnj.h fa0, fa0, fa5742; RV32IFDZFH-NEXT: ret743;744; RV64IFDZFH-LABEL: fold_demote_h_d:745; RV64IFDZFH: # %bb.0:746; RV64IFDZFH-NEXT: fcvt.h.d fa5, fa1747; RV64IFDZFH-NEXT: fsgnj.h fa0, fa0, fa5748; RV64IFDZFH-NEXT: ret749;750; RV32IFZFHMIN-LABEL: fold_demote_h_d:751; RV32IFZFHMIN: # %bb.0:752; RV32IFZFHMIN-NEXT: srli a1, a1, 31753; RV32IFZFHMIN-NEXT: fmv.x.h a0, fa0754; RV32IFZFHMIN-NEXT: slli a1, a1, 15755; RV32IFZFHMIN-NEXT: slli a0, a0, 17756; RV32IFZFHMIN-NEXT: srli a0, a0, 17757; RV32IFZFHMIN-NEXT: or a0, a0, a1758; RV32IFZFHMIN-NEXT: fmv.h.x fa0, a0759; RV32IFZFHMIN-NEXT: ret760;761; RV32IFDZFHMIN-LABEL: fold_demote_h_d:762; RV32IFDZFHMIN: # %bb.0:763; RV32IFDZFHMIN-NEXT: addi sp, sp, -16764; RV32IFDZFHMIN-NEXT: fsd fa1, 8(sp)765; RV32IFDZFHMIN-NEXT: lw a0, 12(sp)766; RV32IFDZFHMIN-NEXT: fmv.x.h a1, fa0767; RV32IFDZFHMIN-NEXT: slli a1, a1, 17768; RV32IFDZFHMIN-NEXT: srli a0, a0, 31769; RV32IFDZFHMIN-NEXT: slli a0, a0, 15770; RV32IFDZFHMIN-NEXT: srli a1, a1, 17771; RV32IFDZFHMIN-NEXT: or a0, a1, a0772; RV32IFDZFHMIN-NEXT: fmv.h.x fa0, a0773; RV32IFDZFHMIN-NEXT: addi sp, sp, 16774; RV32IFDZFHMIN-NEXT: ret775;776; RV64IFDZFHMIN-LABEL: fold_demote_h_d:777; RV64IFDZFHMIN: # %bb.0:778; RV64IFDZFHMIN-NEXT: fmv.x.d a0, fa1779; RV64IFDZFHMIN-NEXT: fmv.x.h a1, fa0780; RV64IFDZFHMIN-NEXT: srli a0, a0, 63781; RV64IFDZFHMIN-NEXT: slli a1, a1, 49782; RV64IFDZFHMIN-NEXT: slli a0, a0, 15783; RV64IFDZFHMIN-NEXT: srli a1, a1, 49784; RV64IFDZFHMIN-NEXT: or a0, a1, a0785; RV64IFDZFHMIN-NEXT: fmv.h.x fa0, a0786; RV64IFDZFHMIN-NEXT: ret787;788; RV32IZDINX-LABEL: fold_demote_h_d:789; RV32IZDINX: # %bb.0:790; RV32IZDINX-NEXT: # kill: def $x10_w killed $x10_w def $x10791; RV32IZDINX-NEXT: lui a1, 524288792; RV32IZDINX-NEXT: slli a0, a0, 17793; RV32IZDINX-NEXT: and a1, a2, a1794; RV32IZDINX-NEXT: lui a2, 1048560795; RV32IZDINX-NEXT: srli a0, a0, 17796; RV32IZDINX-NEXT: srli a1, a1, 16797; RV32IZDINX-NEXT: or a0, a0, a2798; RV32IZDINX-NEXT: or a0, a0, a1799; RV32IZDINX-NEXT: # kill: def $x10_w killed $x10_w killed $x10800; RV32IZDINX-NEXT: ret801;802; RV64IZDINX-LABEL: fold_demote_h_d:803; RV64IZDINX: # %bb.0:804; RV64IZDINX-NEXT: # kill: def $x10_w killed $x10_w def $x10805; RV64IZDINX-NEXT: slli a0, a0, 49806; RV64IZDINX-NEXT: srli a1, a1, 63807; RV64IZDINX-NEXT: lui a2, 1048560808; RV64IZDINX-NEXT: srli a0, a0, 49809; RV64IZDINX-NEXT: slli a1, a1, 63810; RV64IZDINX-NEXT: srli a1, a1, 48811; RV64IZDINX-NEXT: or a0, a0, a2812; RV64IZDINX-NEXT: or a0, a0, a1813; RV64IZDINX-NEXT: # kill: def $x10_w killed $x10_w killed $x10814; RV64IZDINX-NEXT: ret815 %c = fptrunc double %b to half816 %t = call half @llvm.copysign.f16(half %a, half %c)817 ret half %t818}819