1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV32I 4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64I 6; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f \ 7; RUN: -target-abi ilp32f < %s | FileCheck %s -check-prefix=RV32IF 8; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f -mattr=+d \ 9; RUN: -target-abi ilp32d < %s | FileCheck %s -check-prefix=RV32IFD 10; RUN: llc -mtriple=riscv64 -verify-machineinstrs -mattr=+f -mattr=+d \ 11; RUN: -target-abi lp64d < %s | FileCheck %s -check-prefix=RV64IFD 12; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f \ 13; RUN: -mattr=+experimental-zfh -target-abi ilp32f < %s \ 14; RUN: | FileCheck %s -check-prefix=RV32IFZFH 15; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f -mattr=+d \ 16; RUN: -mattr=+experimental-zfh -target-abi ilp32d < %s \ 17; RUN: | FileCheck %s -check-prefix=RV32IFDZFH 18; RUN: llc -mtriple=riscv64 -verify-machineinstrs -mattr=+f -mattr=+d \ 19; RUN: -mattr=+experimental-zfh -target-abi lp64d < %s \ 20; RUN: | FileCheck %s -check-prefix=RV64IFDZFH 21 22; Test fcopysign scenarios where the sign argument is casted to the type of the 23; magnitude argument. Those casts can be folded away by the DAGCombiner. 24 25declare double @llvm.copysign.f64(double, double) 26declare float @llvm.copysign.f32(float, float) 27declare half @llvm.copysign.f16(half, half) 28 29define double @fold_promote_d_s(double %a, float %b) nounwind { 30; RV32I-LABEL: fold_promote_d_s: 31; RV32I: # %bb.0: 32; RV32I-NEXT: lui a3, 524288 33; RV32I-NEXT: and a2, a2, a3 34; RV32I-NEXT: addi a3, a3, -1 35; RV32I-NEXT: and a1, a1, a3 36; RV32I-NEXT: or a1, a1, a2 37; RV32I-NEXT: ret 38; 39; RV64I-LABEL: fold_promote_d_s: 40; RV64I: # %bb.0: 41; RV64I-NEXT: li a2, -1 42; RV64I-NEXT: srli a2, a2, 1 43; RV64I-NEXT: and a0, a0, a2 44; RV64I-NEXT: lui a2, 524288 45; RV64I-NEXT: and a1, a1, a2 46; RV64I-NEXT: slli a1, a1, 32 47; RV64I-NEXT: or a0, a0, a1 48; RV64I-NEXT: ret 49; 50; RV32IF-LABEL: fold_promote_d_s: 51; RV32IF: # %bb.0: 52; RV32IF-NEXT: fmv.x.w a2, fa0 53; RV32IF-NEXT: lui a3, 524288 54; RV32IF-NEXT: and a2, a2, a3 55; RV32IF-NEXT: addi a3, a3, -1 56; RV32IF-NEXT: and a1, a1, a3 57; RV32IF-NEXT: or a1, a1, a2 58; RV32IF-NEXT: ret 59; 60; RV32IFD-LABEL: fold_promote_d_s: 61; RV32IFD: # %bb.0: 62; RV32IFD-NEXT: fcvt.d.s ft0, fa1 63; RV32IFD-NEXT: fsgnj.d fa0, fa0, ft0 64; RV32IFD-NEXT: ret 65; 66; RV64IFD-LABEL: fold_promote_d_s: 67; RV64IFD: # %bb.0: 68; RV64IFD-NEXT: fcvt.d.s ft0, fa1 69; RV64IFD-NEXT: fsgnj.d fa0, fa0, ft0 70; RV64IFD-NEXT: ret 71; 72; RV32IFZFH-LABEL: fold_promote_d_s: 73; RV32IFZFH: # %bb.0: 74; RV32IFZFH-NEXT: fmv.x.w a2, fa0 75; RV32IFZFH-NEXT: lui a3, 524288 76; RV32IFZFH-NEXT: and a2, a2, a3 77; RV32IFZFH-NEXT: addi a3, a3, -1 78; RV32IFZFH-NEXT: and a1, a1, a3 79; RV32IFZFH-NEXT: or a1, a1, a2 80; RV32IFZFH-NEXT: ret 81; 82; RV32IFDZFH-LABEL: fold_promote_d_s: 83; RV32IFDZFH: # %bb.0: 84; RV32IFDZFH-NEXT: fcvt.d.s ft0, fa1 85; RV32IFDZFH-NEXT: fsgnj.d fa0, fa0, ft0 86; RV32IFDZFH-NEXT: ret 87; 88; RV64IFDZFH-LABEL: fold_promote_d_s: 89; RV64IFDZFH: # %bb.0: 90; RV64IFDZFH-NEXT: fcvt.d.s ft0, fa1 91; RV64IFDZFH-NEXT: fsgnj.d fa0, fa0, ft0 92; RV64IFDZFH-NEXT: ret 93 %c = fpext float %b to double 94 %t = call double @llvm.copysign.f64(double %a, double %c) 95 ret double %t 96} 97 98define double @fold_promote_d_h(double %a, half %b) nounwind { 99; RV32I-LABEL: fold_promote_d_h: 100; RV32I: # %bb.0: 101; RV32I-NEXT: lui a3, 524288 102; RV32I-NEXT: addi a3, a3, -1 103; RV32I-NEXT: and a1, a1, a3 104; RV32I-NEXT: lui a3, 8 105; RV32I-NEXT: and a2, a2, a3 106; RV32I-NEXT: slli a2, a2, 16 107; RV32I-NEXT: or a1, a1, a2 108; RV32I-NEXT: ret 109; 110; RV64I-LABEL: fold_promote_d_h: 111; RV64I: # %bb.0: 112; RV64I-NEXT: li a2, -1 113; RV64I-NEXT: srli a2, a2, 1 114; RV64I-NEXT: and a0, a0, a2 115; RV64I-NEXT: lui a2, 8 116; RV64I-NEXT: and a1, a1, a2 117; RV64I-NEXT: slli a1, a1, 48 118; RV64I-NEXT: or a0, a0, a1 119; RV64I-NEXT: ret 120; 121; RV32IF-LABEL: fold_promote_d_h: 122; RV32IF: # %bb.0: 123; RV32IF-NEXT: fmv.x.w a2, fa0 124; RV32IF-NEXT: lui a3, 524288 125; RV32IF-NEXT: addi a3, a3, -1 126; RV32IF-NEXT: and a1, a1, a3 127; RV32IF-NEXT: lui a3, 8 128; RV32IF-NEXT: and a2, a2, a3 129; RV32IF-NEXT: slli a2, a2, 16 130; RV32IF-NEXT: or a1, a1, a2 131; RV32IF-NEXT: ret 132; 133; RV32IFD-LABEL: fold_promote_d_h: 134; RV32IFD: # %bb.0: 135; RV32IFD-NEXT: addi sp, sp, -16 136; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 137; RV32IFD-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill 138; RV32IFD-NEXT: fmv.d fs0, fa0 139; RV32IFD-NEXT: fmv.x.w a0, fa1 140; RV32IFD-NEXT: call __gnu_h2f_ieee@plt 141; RV32IFD-NEXT: fcvt.d.s ft0, fa0 142; RV32IFD-NEXT: fsgnj.d fa0, fs0, ft0 143; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 144; RV32IFD-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload 145; RV32IFD-NEXT: addi sp, sp, 16 146; RV32IFD-NEXT: ret 147; 148; RV64IFD-LABEL: fold_promote_d_h: 149; RV64IFD: # %bb.0: 150; RV64IFD-NEXT: addi sp, sp, -16 151; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 152; RV64IFD-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill 153; RV64IFD-NEXT: fmv.d fs0, fa0 154; RV64IFD-NEXT: fmv.x.w a0, fa1 155; RV64IFD-NEXT: call __gnu_h2f_ieee@plt 156; RV64IFD-NEXT: fcvt.d.s ft0, fa0 157; RV64IFD-NEXT: fsgnj.d fa0, fs0, ft0 158; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 159; RV64IFD-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload 160; RV64IFD-NEXT: addi sp, sp, 16 161; RV64IFD-NEXT: ret 162; 163; RV32IFZFH-LABEL: fold_promote_d_h: 164; RV32IFZFH: # %bb.0: 165; RV32IFZFH-NEXT: fmv.x.h a2, fa0 166; RV32IFZFH-NEXT: lui a3, 524288 167; RV32IFZFH-NEXT: addi a3, a3, -1 168; RV32IFZFH-NEXT: and a1, a1, a3 169; RV32IFZFH-NEXT: lui a3, 8 170; RV32IFZFH-NEXT: and a2, a2, a3 171; RV32IFZFH-NEXT: slli a2, a2, 16 172; RV32IFZFH-NEXT: or a1, a1, a2 173; RV32IFZFH-NEXT: ret 174; 175; RV32IFDZFH-LABEL: fold_promote_d_h: 176; RV32IFDZFH: # %bb.0: 177; RV32IFDZFH-NEXT: fcvt.d.h ft0, fa1 178; RV32IFDZFH-NEXT: fsgnj.d fa0, fa0, ft0 179; RV32IFDZFH-NEXT: ret 180; 181; RV64IFDZFH-LABEL: fold_promote_d_h: 182; RV64IFDZFH: # %bb.0: 183; RV64IFDZFH-NEXT: fcvt.d.h ft0, fa1 184; RV64IFDZFH-NEXT: fsgnj.d fa0, fa0, ft0 185; RV64IFDZFH-NEXT: ret 186 %c = fpext half %b to double 187 %t = call double @llvm.copysign.f64(double %a, double %c) 188 ret double %t 189} 190 191define float @fold_promote_f_h(float %a, half %b) nounwind { 192; RV32I-LABEL: fold_promote_f_h: 193; RV32I: # %bb.0: 194; RV32I-NEXT: lui a2, 524288 195; RV32I-NEXT: addi a2, a2, -1 196; RV32I-NEXT: and a0, a0, a2 197; RV32I-NEXT: lui a2, 8 198; RV32I-NEXT: and a1, a1, a2 199; RV32I-NEXT: slli a1, a1, 16 200; RV32I-NEXT: or a0, a0, a1 201; RV32I-NEXT: ret 202; 203; RV64I-LABEL: fold_promote_f_h: 204; RV64I: # %bb.0: 205; RV64I-NEXT: lui a2, 524288 206; RV64I-NEXT: addiw a2, a2, -1 207; RV64I-NEXT: and a0, a0, a2 208; RV64I-NEXT: lui a2, 8 209; RV64I-NEXT: and a1, a1, a2 210; RV64I-NEXT: slliw a1, a1, 16 211; RV64I-NEXT: or a0, a0, a1 212; RV64I-NEXT: ret 213; 214; RV32IF-LABEL: fold_promote_f_h: 215; RV32IF: # %bb.0: 216; RV32IF-NEXT: addi sp, sp, -16 217; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 218; RV32IF-NEXT: fsw fs0, 8(sp) # 4-byte Folded Spill 219; RV32IF-NEXT: fmv.s fs0, fa0 220; RV32IF-NEXT: fmv.x.w a0, fa1 221; RV32IF-NEXT: call __gnu_h2f_ieee@plt 222; RV32IF-NEXT: fsgnj.s fa0, fs0, fa0 223; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 224; RV32IF-NEXT: flw fs0, 8(sp) # 4-byte Folded Reload 225; RV32IF-NEXT: addi sp, sp, 16 226; RV32IF-NEXT: ret 227; 228; RV32IFD-LABEL: fold_promote_f_h: 229; RV32IFD: # %bb.0: 230; RV32IFD-NEXT: addi sp, sp, -16 231; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill 232; RV32IFD-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill 233; RV32IFD-NEXT: fmv.s fs0, fa0 234; RV32IFD-NEXT: fmv.x.w a0, fa1 235; RV32IFD-NEXT: call __gnu_h2f_ieee@plt 236; RV32IFD-NEXT: fsgnj.s fa0, fs0, fa0 237; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload 238; RV32IFD-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload 239; RV32IFD-NEXT: addi sp, sp, 16 240; RV32IFD-NEXT: ret 241; 242; RV64IFD-LABEL: fold_promote_f_h: 243; RV64IFD: # %bb.0: 244; RV64IFD-NEXT: addi sp, sp, -16 245; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill 246; RV64IFD-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill 247; RV64IFD-NEXT: fmv.s fs0, fa0 248; RV64IFD-NEXT: fmv.x.w a0, fa1 249; RV64IFD-NEXT: call __gnu_h2f_ieee@plt 250; RV64IFD-NEXT: fsgnj.s fa0, fs0, fa0 251; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload 252; RV64IFD-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload 253; RV64IFD-NEXT: addi sp, sp, 16 254; RV64IFD-NEXT: ret 255; 256; RV32IFZFH-LABEL: fold_promote_f_h: 257; RV32IFZFH: # %bb.0: 258; RV32IFZFH-NEXT: fcvt.s.h ft0, fa1 259; RV32IFZFH-NEXT: fsgnj.s fa0, fa0, ft0 260; RV32IFZFH-NEXT: ret 261; 262; RV32IFDZFH-LABEL: fold_promote_f_h: 263; RV32IFDZFH: # %bb.0: 264; RV32IFDZFH-NEXT: fcvt.s.h ft0, fa1 265; RV32IFDZFH-NEXT: fsgnj.s fa0, fa0, ft0 266; RV32IFDZFH-NEXT: ret 267; 268; RV64IFDZFH-LABEL: fold_promote_f_h: 269; RV64IFDZFH: # %bb.0: 270; RV64IFDZFH-NEXT: fcvt.s.h ft0, fa1 271; RV64IFDZFH-NEXT: fsgnj.s fa0, fa0, ft0 272; RV64IFDZFH-NEXT: ret 273 %c = fpext half %b to float 274 %t = call float @llvm.copysign.f32(float %a, float %c) 275 ret float %t 276} 277 278define float @fold_demote_s_d(float %a, double %b) nounwind { 279; RV32I-LABEL: fold_demote_s_d: 280; RV32I: # %bb.0: 281; RV32I-NEXT: lui a1, 524288 282; RV32I-NEXT: and a2, a2, a1 283; RV32I-NEXT: addi a1, a1, -1 284; RV32I-NEXT: and a0, a0, a1 285; RV32I-NEXT: or a0, a0, a2 286; RV32I-NEXT: ret 287; 288; RV64I-LABEL: fold_demote_s_d: 289; RV64I: # %bb.0: 290; RV64I-NEXT: lui a2, 524288 291; RV64I-NEXT: addiw a2, a2, -1 292; RV64I-NEXT: and a0, a0, a2 293; RV64I-NEXT: li a2, -1 294; RV64I-NEXT: slli a2, a2, 63 295; RV64I-NEXT: and a1, a1, a2 296; RV64I-NEXT: srli a1, a1, 32 297; RV64I-NEXT: or a0, a0, a1 298; RV64I-NEXT: ret 299; 300; RV32IF-LABEL: fold_demote_s_d: 301; RV32IF: # %bb.0: 302; RV32IF-NEXT: fmv.w.x ft0, a1 303; RV32IF-NEXT: fsgnj.s fa0, fa0, ft0 304; RV32IF-NEXT: ret 305; 306; RV32IFD-LABEL: fold_demote_s_d: 307; RV32IFD: # %bb.0: 308; RV32IFD-NEXT: fcvt.s.d ft0, fa1 309; RV32IFD-NEXT: fsgnj.s fa0, fa0, ft0 310; RV32IFD-NEXT: ret 311; 312; RV64IFD-LABEL: fold_demote_s_d: 313; RV64IFD: # %bb.0: 314; RV64IFD-NEXT: fcvt.s.d ft0, fa1 315; RV64IFD-NEXT: fsgnj.s fa0, fa0, ft0 316; RV64IFD-NEXT: ret 317; 318; RV32IFZFH-LABEL: fold_demote_s_d: 319; RV32IFZFH: # %bb.0: 320; RV32IFZFH-NEXT: fmv.w.x ft0, a1 321; RV32IFZFH-NEXT: fsgnj.s fa0, fa0, ft0 322; RV32IFZFH-NEXT: ret 323; 324; RV32IFDZFH-LABEL: fold_demote_s_d: 325; RV32IFDZFH: # %bb.0: 326; RV32IFDZFH-NEXT: fcvt.s.d ft0, fa1 327; RV32IFDZFH-NEXT: fsgnj.s fa0, fa0, ft0 328; RV32IFDZFH-NEXT: ret 329; 330; RV64IFDZFH-LABEL: fold_demote_s_d: 331; RV64IFDZFH: # %bb.0: 332; RV64IFDZFH-NEXT: fcvt.s.d ft0, fa1 333; RV64IFDZFH-NEXT: fsgnj.s fa0, fa0, ft0 334; RV64IFDZFH-NEXT: ret 335 %c = fptrunc double %b to float 336 %t = call float @llvm.copysign.f32(float %a, float %c) 337 ret float %t 338} 339 340define half @fold_demote_h_s(half %a, float %b) nounwind { 341; RV32I-LABEL: fold_demote_h_s: 342; RV32I: # %bb.0: 343; RV32I-NEXT: lui a2, 8 344; RV32I-NEXT: addi a2, a2, -1 345; RV32I-NEXT: and a0, a0, a2 346; RV32I-NEXT: lui a2, 524288 347; RV32I-NEXT: and a1, a1, a2 348; RV32I-NEXT: srli a1, a1, 16 349; RV32I-NEXT: or a0, a0, a1 350; RV32I-NEXT: ret 351; 352; RV64I-LABEL: fold_demote_h_s: 353; RV64I: # %bb.0: 354; RV64I-NEXT: lui a2, 8 355; RV64I-NEXT: addiw a2, a2, -1 356; RV64I-NEXT: and a0, a0, a2 357; RV64I-NEXT: li a2, 1 358; RV64I-NEXT: slli a2, a2, 31 359; RV64I-NEXT: and a1, a1, a2 360; RV64I-NEXT: srli a1, a1, 16 361; RV64I-NEXT: or a0, a0, a1 362; RV64I-NEXT: ret 363; 364; RV32IF-LABEL: fold_demote_h_s: 365; RV32IF: # %bb.0: 366; RV32IF-NEXT: fmv.x.w a0, fa1 367; RV32IF-NEXT: fmv.x.w a1, fa0 368; RV32IF-NEXT: lui a2, 8 369; RV32IF-NEXT: addi a2, a2, -1 370; RV32IF-NEXT: and a1, a1, a2 371; RV32IF-NEXT: lui a2, 524288 372; RV32IF-NEXT: and a0, a0, a2 373; RV32IF-NEXT: srli a0, a0, 16 374; RV32IF-NEXT: or a0, a1, a0 375; RV32IF-NEXT: lui a1, 1048560 376; RV32IF-NEXT: or a0, a0, a1 377; RV32IF-NEXT: fmv.w.x fa0, a0 378; RV32IF-NEXT: ret 379; 380; RV32IFD-LABEL: fold_demote_h_s: 381; RV32IFD: # %bb.0: 382; RV32IFD-NEXT: fmv.x.w a0, fa1 383; RV32IFD-NEXT: fmv.x.w a1, fa0 384; RV32IFD-NEXT: lui a2, 8 385; RV32IFD-NEXT: addi a2, a2, -1 386; RV32IFD-NEXT: and a1, a1, a2 387; RV32IFD-NEXT: lui a2, 524288 388; RV32IFD-NEXT: and a0, a0, a2 389; RV32IFD-NEXT: srli a0, a0, 16 390; RV32IFD-NEXT: or a0, a1, a0 391; RV32IFD-NEXT: lui a1, 1048560 392; RV32IFD-NEXT: or a0, a0, a1 393; RV32IFD-NEXT: fmv.w.x fa0, a0 394; RV32IFD-NEXT: ret 395; 396; RV64IFD-LABEL: fold_demote_h_s: 397; RV64IFD: # %bb.0: 398; RV64IFD-NEXT: fmv.x.w a0, fa1 399; RV64IFD-NEXT: fmv.x.w a1, fa0 400; RV64IFD-NEXT: lui a2, 8 401; RV64IFD-NEXT: addiw a2, a2, -1 402; RV64IFD-NEXT: and a1, a1, a2 403; RV64IFD-NEXT: lui a2, 524288 404; RV64IFD-NEXT: and a0, a0, a2 405; RV64IFD-NEXT: srli a0, a0, 16 406; RV64IFD-NEXT: or a0, a1, a0 407; RV64IFD-NEXT: lui a1, 1048560 408; RV64IFD-NEXT: or a0, a0, a1 409; RV64IFD-NEXT: fmv.w.x fa0, a0 410; RV64IFD-NEXT: ret 411; 412; RV32IFZFH-LABEL: fold_demote_h_s: 413; RV32IFZFH: # %bb.0: 414; RV32IFZFH-NEXT: fcvt.h.s ft0, fa1 415; RV32IFZFH-NEXT: fsgnj.h fa0, fa0, ft0 416; RV32IFZFH-NEXT: ret 417; 418; RV32IFDZFH-LABEL: fold_demote_h_s: 419; RV32IFDZFH: # %bb.0: 420; RV32IFDZFH-NEXT: fcvt.h.s ft0, fa1 421; RV32IFDZFH-NEXT: fsgnj.h fa0, fa0, ft0 422; RV32IFDZFH-NEXT: ret 423; 424; RV64IFDZFH-LABEL: fold_demote_h_s: 425; RV64IFDZFH: # %bb.0: 426; RV64IFDZFH-NEXT: fcvt.h.s ft0, fa1 427; RV64IFDZFH-NEXT: fsgnj.h fa0, fa0, ft0 428; RV64IFDZFH-NEXT: ret 429 %c = fptrunc float %b to half 430 %t = call half @llvm.copysign.f16(half %a, half %c) 431 ret half %t 432} 433 434define half @fold_demote_h_d(half %a, double %b) nounwind { 435; RV32I-LABEL: fold_demote_h_d: 436; RV32I: # %bb.0: 437; RV32I-NEXT: lui a1, 8 438; RV32I-NEXT: addi a1, a1, -1 439; RV32I-NEXT: and a0, a0, a1 440; RV32I-NEXT: lui a1, 524288 441; RV32I-NEXT: and a1, a2, a1 442; RV32I-NEXT: srli a1, a1, 16 443; RV32I-NEXT: or a0, a0, a1 444; RV32I-NEXT: ret 445; 446; RV64I-LABEL: fold_demote_h_d: 447; RV64I: # %bb.0: 448; RV64I-NEXT: lui a2, 8 449; RV64I-NEXT: addiw a2, a2, -1 450; RV64I-NEXT: and a0, a0, a2 451; RV64I-NEXT: li a2, -1 452; RV64I-NEXT: slli a2, a2, 63 453; RV64I-NEXT: and a1, a1, a2 454; RV64I-NEXT: srli a1, a1, 48 455; RV64I-NEXT: or a0, a0, a1 456; RV64I-NEXT: ret 457; 458; RV32IF-LABEL: fold_demote_h_d: 459; RV32IF: # %bb.0: 460; RV32IF-NEXT: fmv.x.w a0, fa0 461; RV32IF-NEXT: lui a2, 8 462; RV32IF-NEXT: addi a2, a2, -1 463; RV32IF-NEXT: and a0, a0, a2 464; RV32IF-NEXT: lui a2, 524288 465; RV32IF-NEXT: and a1, a1, a2 466; RV32IF-NEXT: srli a1, a1, 16 467; RV32IF-NEXT: or a0, a0, a1 468; RV32IF-NEXT: lui a1, 1048560 469; RV32IF-NEXT: or a0, a0, a1 470; RV32IF-NEXT: fmv.w.x fa0, a0 471; RV32IF-NEXT: ret 472; 473; RV32IFD-LABEL: fold_demote_h_d: 474; RV32IFD: # %bb.0: 475; RV32IFD-NEXT: addi sp, sp, -16 476; RV32IFD-NEXT: fsd fa1, 8(sp) 477; RV32IFD-NEXT: fmv.x.w a0, fa0 478; RV32IFD-NEXT: lw a1, 12(sp) 479; RV32IFD-NEXT: lui a2, 8 480; RV32IFD-NEXT: addi a2, a2, -1 481; RV32IFD-NEXT: and a0, a0, a2 482; RV32IFD-NEXT: lui a2, 524288 483; RV32IFD-NEXT: and a1, a1, a2 484; RV32IFD-NEXT: srli a1, a1, 16 485; RV32IFD-NEXT: or a0, a0, a1 486; RV32IFD-NEXT: lui a1, 1048560 487; RV32IFD-NEXT: or a0, a0, a1 488; RV32IFD-NEXT: fmv.w.x fa0, a0 489; RV32IFD-NEXT: addi sp, sp, 16 490; RV32IFD-NEXT: ret 491; 492; RV64IFD-LABEL: fold_demote_h_d: 493; RV64IFD: # %bb.0: 494; RV64IFD-NEXT: fmv.x.d a0, fa1 495; RV64IFD-NEXT: fmv.x.w a1, fa0 496; RV64IFD-NEXT: lui a2, 8 497; RV64IFD-NEXT: addiw a2, a2, -1 498; RV64IFD-NEXT: and a1, a1, a2 499; RV64IFD-NEXT: li a2, -1 500; RV64IFD-NEXT: slli a2, a2, 63 501; RV64IFD-NEXT: and a0, a0, a2 502; RV64IFD-NEXT: srli a0, a0, 48 503; RV64IFD-NEXT: or a0, a1, a0 504; RV64IFD-NEXT: lui a1, 1048560 505; RV64IFD-NEXT: or a0, a0, a1 506; RV64IFD-NEXT: fmv.w.x fa0, a0 507; RV64IFD-NEXT: ret 508; 509; RV32IFZFH-LABEL: fold_demote_h_d: 510; RV32IFZFH: # %bb.0: 511; RV32IFZFH-NEXT: srli a0, a1, 16 512; RV32IFZFH-NEXT: fmv.h.x ft0, a0 513; RV32IFZFH-NEXT: fsgnj.h fa0, fa0, ft0 514; RV32IFZFH-NEXT: ret 515; 516; RV32IFDZFH-LABEL: fold_demote_h_d: 517; RV32IFDZFH: # %bb.0: 518; RV32IFDZFH-NEXT: fcvt.h.d ft0, fa1 519; RV32IFDZFH-NEXT: fsgnj.h fa0, fa0, ft0 520; RV32IFDZFH-NEXT: ret 521; 522; RV64IFDZFH-LABEL: fold_demote_h_d: 523; RV64IFDZFH: # %bb.0: 524; RV64IFDZFH-NEXT: fcvt.h.d ft0, fa1 525; RV64IFDZFH-NEXT: fsgnj.h fa0, fa0, ft0 526; RV64IFDZFH-NEXT: ret 527 %c = fptrunc double %b to half 528 %t = call half @llvm.copysign.f16(half %a, half %c) 529 ret half %t 530} 531