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