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 __extendhfsf2@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 __extendhfsf2@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 __extendhfsf2@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 __extendhfsf2@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 __extendhfsf2@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: slli a0, a0, 33 284; RV64I-NEXT: srli a0, a0, 33 285; RV64I-NEXT: srli a1, a1, 63 286; RV64I-NEXT: slli a1, a1, 63 287; RV64I-NEXT: srli a1, a1, 32 288; RV64I-NEXT: or a0, a0, a1 289; RV64I-NEXT: ret 290; 291; RV32IF-LABEL: fold_demote_s_d: 292; RV32IF: # %bb.0: 293; RV32IF-NEXT: fmv.w.x ft0, a1 294; RV32IF-NEXT: fsgnj.s fa0, fa0, ft0 295; RV32IF-NEXT: ret 296; 297; RV32IFD-LABEL: fold_demote_s_d: 298; RV32IFD: # %bb.0: 299; RV32IFD-NEXT: fcvt.s.d ft0, fa1 300; RV32IFD-NEXT: fsgnj.s fa0, fa0, ft0 301; RV32IFD-NEXT: ret 302; 303; RV64IFD-LABEL: fold_demote_s_d: 304; RV64IFD: # %bb.0: 305; RV64IFD-NEXT: fcvt.s.d ft0, fa1 306; RV64IFD-NEXT: fsgnj.s fa0, fa0, ft0 307; RV64IFD-NEXT: ret 308; 309; RV32IFZFH-LABEL: fold_demote_s_d: 310; RV32IFZFH: # %bb.0: 311; RV32IFZFH-NEXT: fmv.w.x ft0, a1 312; RV32IFZFH-NEXT: fsgnj.s fa0, fa0, ft0 313; RV32IFZFH-NEXT: ret 314; 315; RV32IFDZFH-LABEL: fold_demote_s_d: 316; RV32IFDZFH: # %bb.0: 317; RV32IFDZFH-NEXT: fcvt.s.d ft0, fa1 318; RV32IFDZFH-NEXT: fsgnj.s fa0, fa0, ft0 319; RV32IFDZFH-NEXT: ret 320; 321; RV64IFDZFH-LABEL: fold_demote_s_d: 322; RV64IFDZFH: # %bb.0: 323; RV64IFDZFH-NEXT: fcvt.s.d ft0, fa1 324; RV64IFDZFH-NEXT: fsgnj.s fa0, fa0, ft0 325; RV64IFDZFH-NEXT: ret 326 %c = fptrunc double %b to float 327 %t = call float @llvm.copysign.f32(float %a, float %c) 328 ret float %t 329} 330 331define half @fold_demote_h_s(half %a, float %b) nounwind { 332; RV32I-LABEL: fold_demote_h_s: 333; RV32I: # %bb.0: 334; RV32I-NEXT: lui a2, 524288 335; RV32I-NEXT: and a1, a1, a2 336; RV32I-NEXT: srli a1, a1, 16 337; RV32I-NEXT: slli a0, a0, 17 338; RV32I-NEXT: srli a0, a0, 17 339; RV32I-NEXT: or a0, a0, a1 340; RV32I-NEXT: ret 341; 342; RV64I-LABEL: fold_demote_h_s: 343; RV64I: # %bb.0: 344; RV64I-NEXT: srliw a1, a1, 31 345; RV64I-NEXT: slli a1, a1, 15 346; RV64I-NEXT: slli a0, a0, 49 347; RV64I-NEXT: srli a0, a0, 49 348; RV64I-NEXT: or a0, a0, a1 349; RV64I-NEXT: ret 350; 351; RV32IF-LABEL: fold_demote_h_s: 352; RV32IF: # %bb.0: 353; RV32IF-NEXT: fmv.x.w a0, fa0 354; RV32IF-NEXT: fmv.x.w a1, fa1 355; RV32IF-NEXT: lui a2, 524288 356; RV32IF-NEXT: and a1, a1, a2 357; RV32IF-NEXT: srli a1, a1, 16 358; RV32IF-NEXT: slli a0, a0, 17 359; RV32IF-NEXT: srli a0, a0, 17 360; RV32IF-NEXT: or a0, a0, a1 361; RV32IF-NEXT: lui a1, 1048560 362; RV32IF-NEXT: or a0, a0, a1 363; RV32IF-NEXT: fmv.w.x fa0, a0 364; RV32IF-NEXT: ret 365; 366; RV32IFD-LABEL: fold_demote_h_s: 367; RV32IFD: # %bb.0: 368; RV32IFD-NEXT: fmv.x.w a0, fa0 369; RV32IFD-NEXT: fmv.x.w a1, fa1 370; RV32IFD-NEXT: lui a2, 524288 371; RV32IFD-NEXT: and a1, a1, a2 372; RV32IFD-NEXT: srli a1, a1, 16 373; RV32IFD-NEXT: slli a0, a0, 17 374; RV32IFD-NEXT: srli a0, a0, 17 375; RV32IFD-NEXT: or a0, a0, a1 376; RV32IFD-NEXT: lui a1, 1048560 377; RV32IFD-NEXT: or a0, a0, a1 378; RV32IFD-NEXT: fmv.w.x fa0, a0 379; RV32IFD-NEXT: ret 380; 381; RV64IFD-LABEL: fold_demote_h_s: 382; RV64IFD: # %bb.0: 383; RV64IFD-NEXT: fmv.x.w a0, fa0 384; RV64IFD-NEXT: fmv.x.w a1, fa1 385; RV64IFD-NEXT: lui a2, 524288 386; RV64IFD-NEXT: and a1, a1, a2 387; RV64IFD-NEXT: srli a1, a1, 16 388; RV64IFD-NEXT: slli a0, a0, 49 389; RV64IFD-NEXT: srli a0, a0, 49 390; RV64IFD-NEXT: or a0, a0, a1 391; RV64IFD-NEXT: lui a1, 1048560 392; RV64IFD-NEXT: or a0, a0, a1 393; RV64IFD-NEXT: fmv.w.x fa0, a0 394; RV64IFD-NEXT: ret 395; 396; RV32IFZFH-LABEL: fold_demote_h_s: 397; RV32IFZFH: # %bb.0: 398; RV32IFZFH-NEXT: fcvt.h.s ft0, fa1 399; RV32IFZFH-NEXT: fsgnj.h fa0, fa0, ft0 400; RV32IFZFH-NEXT: ret 401; 402; RV32IFDZFH-LABEL: fold_demote_h_s: 403; RV32IFDZFH: # %bb.0: 404; RV32IFDZFH-NEXT: fcvt.h.s ft0, fa1 405; RV32IFDZFH-NEXT: fsgnj.h fa0, fa0, ft0 406; RV32IFDZFH-NEXT: ret 407; 408; RV64IFDZFH-LABEL: fold_demote_h_s: 409; RV64IFDZFH: # %bb.0: 410; RV64IFDZFH-NEXT: fcvt.h.s ft0, fa1 411; RV64IFDZFH-NEXT: fsgnj.h fa0, fa0, ft0 412; RV64IFDZFH-NEXT: ret 413 %c = fptrunc float %b to half 414 %t = call half @llvm.copysign.f16(half %a, half %c) 415 ret half %t 416} 417 418define half @fold_demote_h_d(half %a, double %b) nounwind { 419; RV32I-LABEL: fold_demote_h_d: 420; RV32I: # %bb.0: 421; RV32I-NEXT: lui a1, 524288 422; RV32I-NEXT: and a1, a2, a1 423; RV32I-NEXT: srli a1, a1, 16 424; RV32I-NEXT: slli a0, a0, 17 425; RV32I-NEXT: srli a0, a0, 17 426; RV32I-NEXT: or a0, a0, a1 427; RV32I-NEXT: ret 428; 429; RV64I-LABEL: fold_demote_h_d: 430; RV64I: # %bb.0: 431; RV64I-NEXT: slli a0, a0, 49 432; RV64I-NEXT: srli a0, a0, 49 433; RV64I-NEXT: srli a1, a1, 63 434; RV64I-NEXT: slli a1, a1, 63 435; RV64I-NEXT: srli a1, a1, 48 436; RV64I-NEXT: or a0, a0, a1 437; RV64I-NEXT: ret 438; 439; RV32IF-LABEL: fold_demote_h_d: 440; RV32IF: # %bb.0: 441; RV32IF-NEXT: fmv.x.w a0, fa0 442; RV32IF-NEXT: lui a2, 524288 443; RV32IF-NEXT: and a1, a1, a2 444; RV32IF-NEXT: srli a1, a1, 16 445; RV32IF-NEXT: slli a0, a0, 17 446; RV32IF-NEXT: srli a0, a0, 17 447; RV32IF-NEXT: or a0, a0, a1 448; RV32IF-NEXT: lui a1, 1048560 449; RV32IF-NEXT: or a0, a0, a1 450; RV32IF-NEXT: fmv.w.x fa0, a0 451; RV32IF-NEXT: ret 452; 453; RV32IFD-LABEL: fold_demote_h_d: 454; RV32IFD: # %bb.0: 455; RV32IFD-NEXT: addi sp, sp, -16 456; RV32IFD-NEXT: fsd fa1, 8(sp) 457; RV32IFD-NEXT: lw a0, 12(sp) 458; RV32IFD-NEXT: fmv.x.w a1, fa0 459; RV32IFD-NEXT: lui a2, 524288 460; RV32IFD-NEXT: and a0, a0, a2 461; RV32IFD-NEXT: srli a0, a0, 16 462; RV32IFD-NEXT: slli a1, a1, 17 463; RV32IFD-NEXT: srli a1, a1, 17 464; RV32IFD-NEXT: or a0, a1, a0 465; RV32IFD-NEXT: lui a1, 1048560 466; RV32IFD-NEXT: or a0, a0, a1 467; RV32IFD-NEXT: fmv.w.x fa0, a0 468; RV32IFD-NEXT: addi sp, sp, 16 469; RV32IFD-NEXT: ret 470; 471; RV64IFD-LABEL: fold_demote_h_d: 472; RV64IFD: # %bb.0: 473; RV64IFD-NEXT: fmv.x.d a0, fa1 474; RV64IFD-NEXT: fmv.x.w a1, fa0 475; RV64IFD-NEXT: slli a1, a1, 49 476; RV64IFD-NEXT: srli a1, a1, 49 477; RV64IFD-NEXT: srli a0, a0, 63 478; RV64IFD-NEXT: slli a0, a0, 63 479; RV64IFD-NEXT: srli a0, a0, 48 480; RV64IFD-NEXT: or a0, a1, a0 481; RV64IFD-NEXT: lui a1, 1048560 482; RV64IFD-NEXT: or a0, a0, a1 483; RV64IFD-NEXT: fmv.w.x fa0, a0 484; RV64IFD-NEXT: ret 485; 486; RV32IFZFH-LABEL: fold_demote_h_d: 487; RV32IFZFH: # %bb.0: 488; RV32IFZFH-NEXT: srli a0, a1, 16 489; RV32IFZFH-NEXT: fmv.h.x ft0, a0 490; RV32IFZFH-NEXT: fsgnj.h fa0, fa0, ft0 491; RV32IFZFH-NEXT: ret 492; 493; RV32IFDZFH-LABEL: fold_demote_h_d: 494; RV32IFDZFH: # %bb.0: 495; RV32IFDZFH-NEXT: fcvt.h.d ft0, fa1 496; RV32IFDZFH-NEXT: fsgnj.h fa0, fa0, ft0 497; RV32IFDZFH-NEXT: ret 498; 499; RV64IFDZFH-LABEL: fold_demote_h_d: 500; RV64IFDZFH: # %bb.0: 501; RV64IFDZFH-NEXT: fcvt.h.d ft0, fa1 502; RV64IFDZFH-NEXT: fsgnj.h fa0, fa0, ft0 503; RV64IFDZFH-NEXT: ret 504 %c = fptrunc double %b to half 505 %t = call half @llvm.copysign.f16(half %a, half %c) 506 ret half %t 507} 508