1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 2; RUN: llc -mtriple=riscv32 -mattr=+zdinx -verify-machineinstrs < %s \ 3; RUN: -target-abi=ilp32 -mattr=+zhinx | FileCheck %s 4 5;; These tests cover the use of `r`, `R`, and `cr` constraints for floating point values on rv32. 6;; 7;; In particular, there is significant complexity around using paired GPRs for double values on rv32. 8 9define dso_local void @zdinx_asm(ptr nocapture noundef writeonly %a, double noundef %b, double noundef %c) nounwind { 10; CHECK-LABEL: zdinx_asm: 11; CHECK: # %bb.0: # %entry 12; CHECK-NEXT: mv a5, a4 13; CHECK-NEXT: mv a7, a2 14; CHECK-NEXT: mv a4, a3 15; CHECK-NEXT: mv a6, a1 16; CHECK-NEXT: #APP 17; CHECK-NEXT: fsgnjx.d a2, a6, a4 18; CHECK-NEXT: #NO_APP 19; CHECK-NEXT: sw a2, 8(a0) 20; CHECK-NEXT: sw a3, 12(a0) 21; CHECK-NEXT: ret 22entry: 23 %arrayidx = getelementptr inbounds double, ptr %a, i32 1 24 %0 = tail call double asm "fsgnjx.d $0, $1, $2", "=r,r,r"(double %b, double %c) 25 store double %0, ptr %arrayidx, align 8 26 ret void 27} 28 29define dso_local void @zdinx_asm_R(ptr nocapture noundef writeonly %a, double noundef %b, double noundef %c) nounwind { 30; CHECK-LABEL: zdinx_asm_R: 31; CHECK: # %bb.0: # %entry 32; CHECK-NEXT: mv a5, a4 33; CHECK-NEXT: mv a7, a2 34; CHECK-NEXT: mv a4, a3 35; CHECK-NEXT: mv a6, a1 36; CHECK-NEXT: #APP 37; CHECK-NEXT: fsgnjx.d a2, a6, a4 38; CHECK-NEXT: #NO_APP 39; CHECK-NEXT: sw a2, 8(a0) 40; CHECK-NEXT: sw a3, 12(a0) 41; CHECK-NEXT: ret 42entry: 43 %arrayidx = getelementptr inbounds double, ptr %a, i32 1 44 %0 = tail call double asm "fsgnjx.d $0, $1, $2", "=R,R,R"(double %b, double %c) 45 store double %0, ptr %arrayidx, align 8 46 ret void 47} 48 49define dso_local void @zdinx_asm_inout(ptr nocapture noundef writeonly %a, double noundef %b) nounwind { 50; CHECK-LABEL: zdinx_asm_inout: 51; CHECK: # %bb.0: # %entry 52; CHECK-NEXT: mv a3, a2 53; CHECK-NEXT: mv a2, a1 54; CHECK-NEXT: #APP 55; CHECK-NEXT: fmv.d a2, a2 56; CHECK-NEXT: #NO_APP 57; CHECK-NEXT: sw a2, 8(a0) 58; CHECK-NEXT: sw a3, 12(a0) 59; CHECK-NEXT: ret 60entry: 61 %arrayidx = getelementptr inbounds double, ptr %a, i32 1 62 %0 = tail call double asm "fsgnj.d $0, $1, $1", "=r,0"(double %b) 63 store double %0, ptr %arrayidx, align 8 64 ret void 65} 66 67define dso_local void @zdinx_asm_Pr_inout(ptr nocapture noundef writeonly %a, double noundef %b) nounwind { 68; CHECK-LABEL: zdinx_asm_Pr_inout: 69; CHECK: # %bb.0: # %entry 70; CHECK-NEXT: mv a3, a2 71; CHECK-NEXT: mv a2, a1 72; CHECK-NEXT: #APP 73; CHECK-NEXT: fabs.d a2, a2 74; CHECK-NEXT: #NO_APP 75; CHECK-NEXT: sw a2, 8(a0) 76; CHECK-NEXT: sw a3, 12(a0) 77; CHECK-NEXT: ret 78entry: 79 %arrayidx = getelementptr inbounds double, ptr %a, i32 1 80 %0 = tail call double asm "fsgnjx.d $0, $1, $1", "=R,0"(double %b) 81 store double %0, ptr %arrayidx, align 8 82 ret void 83} 84 85define dso_local void @zdinx_asm_cR_inout(ptr nocapture noundef writeonly %a, double noundef %b) nounwind { 86; CHECK-LABEL: zdinx_asm_cR_inout: 87; CHECK: # %bb.0: # %entry 88; CHECK-NEXT: mv a3, a2 89; CHECK-NEXT: mv a2, a1 90; CHECK-NEXT: #APP 91; CHECK-NEXT: fabs.d a2, a2 92; CHECK-NEXT: #NO_APP 93; CHECK-NEXT: sw a2, 8(a0) 94; CHECK-NEXT: sw a3, 12(a0) 95; CHECK-NEXT: ret 96entry: 97 %arrayidx = getelementptr inbounds double, ptr %a, i32 1 98 %0 = tail call double asm "fsgnjx.d $0, $1, $1", "=^cR,0"(double %b) 99 store double %0, ptr %arrayidx, align 8 100 ret void 101} 102 103define dso_local void @zfinx_asm(ptr nocapture noundef writeonly %a, float noundef %b, float noundef %c) nounwind { 104; CHECK-LABEL: zfinx_asm: 105; CHECK: # %bb.0: # %entry 106; CHECK-NEXT: #APP 107; CHECK-NEXT: fsgnjx.s a1, a1, a2 108; CHECK-NEXT: #NO_APP 109; CHECK-NEXT: sw a1, 4(a0) 110; CHECK-NEXT: ret 111entry: 112 %arrayidx = getelementptr inbounds float, ptr %a, i32 1 113 %0 = tail call float asm "fsgnjx.s $0, $1, $2", "=r,r,r"(float %b, float %c) 114 store float %0, ptr %arrayidx, align 8 115 ret void 116} 117 118define dso_local void @zhinx_asm(ptr nocapture noundef writeonly %a, half noundef %b, half noundef %c) nounwind { 119; CHECK-LABEL: zhinx_asm: 120; CHECK: # %bb.0: # %entry 121; CHECK-NEXT: #APP 122; CHECK-NEXT: fsgnjx.h a1, a1, a2 123; CHECK-NEXT: #NO_APP 124; CHECK-NEXT: sh a1, 2(a0) 125; CHECK-NEXT: ret 126entry: 127 %arrayidx = getelementptr inbounds half, ptr %a, i32 1 128 %0 = tail call half asm "fsgnjx.h $0, $1, $2", "=r,r,r"(half %b, half %c) 129 store half %0, ptr %arrayidx, align 8 130 ret void 131} 132 133define dso_local void @zdinx_asm_cr(ptr nocapture noundef writeonly %a, double noundef %b, double noundef %c) nounwind { 134; CHECK-LABEL: zdinx_asm_cr: 135; CHECK: # %bb.0: # %entry 136; CHECK-NEXT: addi sp, sp, -16 137; CHECK-NEXT: sw s0, 12(sp) # 4-byte Folded Spill 138; CHECK-NEXT: sw s1, 8(sp) # 4-byte Folded Spill 139; CHECK-NEXT: mv a5, a4 140; CHECK-NEXT: mv s1, a2 141; CHECK-NEXT: mv a4, a3 142; CHECK-NEXT: mv s0, a1 143; CHECK-NEXT: #APP 144; CHECK-NEXT: fsgnjx.d a2, s0, a4 145; CHECK-NEXT: #NO_APP 146; CHECK-NEXT: sw a2, 8(a0) 147; CHECK-NEXT: sw a3, 12(a0) 148; CHECK-NEXT: lw s0, 12(sp) # 4-byte Folded Reload 149; CHECK-NEXT: lw s1, 8(sp) # 4-byte Folded Reload 150; CHECK-NEXT: addi sp, sp, 16 151; CHECK-NEXT: ret 152entry: 153 %arrayidx = getelementptr inbounds double, ptr %a, i32 1 154 %0 = tail call double asm "fsgnjx.d $0, $1, $2", "=^cr,^cr,^cr"(double %b, double %c) 155 store double %0, ptr %arrayidx, align 8 156 ret void 157} 158 159define dso_local void @zfinx_asm_cr(ptr nocapture noundef writeonly %a, float noundef %b, float noundef %c) nounwind { 160; CHECK-LABEL: zfinx_asm_cr: 161; CHECK: # %bb.0: # %entry 162; CHECK-NEXT: #APP 163; CHECK-NEXT: fsgnjx.s a1, a1, a2 164; CHECK-NEXT: #NO_APP 165; CHECK-NEXT: sw a1, 4(a0) 166; CHECK-NEXT: ret 167entry: 168 %arrayidx = getelementptr inbounds float, ptr %a, i32 1 169 %0 = tail call float asm "fsgnjx.s $0, $1, $2", "=^cr,^cr,^cr"(float %b, float %c) 170 store float %0, ptr %arrayidx, align 8 171 ret void 172} 173 174define dso_local void @zhinx_asm_cr(ptr nocapture noundef writeonly %a, half noundef %b, half noundef %c) nounwind { 175; CHECK-LABEL: zhinx_asm_cr: 176; CHECK: # %bb.0: # %entry 177; CHECK-NEXT: #APP 178; CHECK-NEXT: fsgnjx.h a1, a1, a2 179; CHECK-NEXT: #NO_APP 180; CHECK-NEXT: sh a1, 2(a0) 181; CHECK-NEXT: ret 182entry: 183 %arrayidx = getelementptr inbounds half, ptr %a, i32 1 184 %0 = tail call half asm "fsgnjx.h $0, $1, $2", "=^cr,^cr,^cr"(half %b, half %c) 185 store half %0, ptr %arrayidx, align 8 186 ret void 187} 188 189define dso_local void @zdinx_asm_cR(ptr nocapture noundef writeonly %a, double noundef %b, double noundef %c) nounwind { 190; CHECK-LABEL: zdinx_asm_cR: 191; CHECK: # %bb.0: # %entry 192; CHECK-NEXT: addi sp, sp, -16 193; CHECK-NEXT: sw s0, 12(sp) # 4-byte Folded Spill 194; CHECK-NEXT: sw s1, 8(sp) # 4-byte Folded Spill 195; CHECK-NEXT: mv a5, a4 196; CHECK-NEXT: mv s1, a2 197; CHECK-NEXT: mv a4, a3 198; CHECK-NEXT: mv s0, a1 199; CHECK-NEXT: #APP 200; CHECK-NEXT: fsgnjx.d a2, s0, a4 201; CHECK-NEXT: #NO_APP 202; CHECK-NEXT: sw a2, 8(a0) 203; CHECK-NEXT: sw a3, 12(a0) 204; CHECK-NEXT: lw s0, 12(sp) # 4-byte Folded Reload 205; CHECK-NEXT: lw s1, 8(sp) # 4-byte Folded Reload 206; CHECK-NEXT: addi sp, sp, 16 207; CHECK-NEXT: ret 208entry: 209 %arrayidx = getelementptr inbounds double, ptr %a, i32 1 210 %0 = tail call double asm "fsgnjx.d $0, $1, $2", "=^cR,^cR,^cR"(double %b, double %c) 211 store double %0, ptr %arrayidx, align 8 212 ret void 213} 214