1; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 2; RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-linux-gnu < %s \ 3; RUN: -stop-after=finalize-isel -verify-machineinstrs | FileCheck %s 4 5; Verify if the mayRaiseFPException is set for FCMPD/FCMPS 6define i32 @fcmpu(double %a, double %b) { 7 ; CHECK-LABEL: name: fcmpu 8 ; CHECK: bb.0.entry: 9 ; CHECK-NEXT: liveins: $f1, $f2 10 ; CHECK-NEXT: {{ $}} 11 ; CHECK-NEXT: [[COPY:%[0-9]+]]:f8rc = COPY $f2 12 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:f8rc = COPY $f1 13 ; CHECK-NEXT: [[FCMPUD:%[0-9]+]]:crrc = nofpexcept FCMPUD [[COPY1]], [[COPY]] 14 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:crbitrc = COPY [[FCMPUD]].sub_gt 15 ; CHECK-NEXT: [[LI8_:%[0-9]+]]:g8rc_and_g8rc_nox0 = LI8 0 16 ; CHECK-NEXT: [[LI8_1:%[0-9]+]]:g8rc_and_g8rc_nox0 = LI8 1 17 ; CHECK-NEXT: [[ISEL8_:%[0-9]+]]:g8rc = ISEL8 [[LI8_1]], [[LI8_]], [[COPY2]] 18 ; CHECK-NEXT: $x3 = COPY [[ISEL8_]] 19 ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $x3 20entry: 21 %r = fcmp ogt double %a, %b 22 %g = zext i1 %r to i32 23 ret i32 %g 24} 25 26define double @max_typec(double %a, double %b) { 27 ; CHECK-LABEL: name: max_typec 28 ; CHECK: bb.0.entry: 29 ; CHECK-NEXT: liveins: $f1, $f2 30 ; CHECK-NEXT: {{ $}} 31 ; CHECK-NEXT: [[COPY:%[0-9]+]]:vsfrc = COPY $f2 32 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vsfrc = COPY $f1 33 ; CHECK-NEXT: [[XSMAXCDP:%[0-9]+]]:vsfrc = nofpexcept XSMAXCDP [[COPY1]], [[COPY]] 34 ; CHECK-NEXT: $f1 = COPY [[XSMAXCDP]] 35 ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $f1 36entry: 37 %cmp = fcmp ogt double %a, %b 38 %sel = select i1 %cmp, double %a, double %b 39 ret double %sel 40} 41 42; Verify no mayRaiseFPException bit set on fneg & fabs 43define double @fneg(double %a) { 44 ; CHECK-LABEL: name: fneg 45 ; CHECK: bb.0.entry: 46 ; CHECK-NEXT: liveins: $f1 47 ; CHECK-NEXT: {{ $}} 48 ; CHECK-NEXT: [[COPY:%[0-9]+]]:vsfrc = COPY $f1 49 ; CHECK-NEXT: [[XSNEGDP:%[0-9]+]]:vsfrc = XSNEGDP [[COPY]], implicit $rm 50 ; CHECK-NEXT: $f1 = COPY [[XSNEGDP]] 51 ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $f1 52entry: 53 %neg = fneg double %a 54 ret double %neg 55} 56 57define double @fabs(double %a) { 58 ; CHECK-LABEL: name: fabs 59 ; CHECK: bb.0.entry: 60 ; CHECK-NEXT: liveins: $f1 61 ; CHECK-NEXT: {{ $}} 62 ; CHECK-NEXT: [[COPY:%[0-9]+]]:vsfrc = COPY $f1 63 ; CHECK-NEXT: [[XSABSDP:%[0-9]+]]:vsfrc = XSABSDP [[COPY]], implicit $rm 64 ; CHECK-NEXT: $f1 = COPY [[XSABSDP]] 65 ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $f1 66entry: 67 %abs = call double @llvm.fabs.f64(double %a) 68 ret double %abs 69} 70 71; Verify nofpexcept is set to constrained conversions when ignoring exceptions 72define void @fptoint_nofpexcept(ppc_fp128 %p, fp128 %m, ptr %addr1, ptr %addr2) #0 { 73 ; CHECK-LABEL: name: fptoint_nofpexcept 74 ; CHECK: bb.0.entry: 75 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) 76 ; CHECK-NEXT: liveins: $f1, $f2, $v2, $x7, $x8 77 ; CHECK-NEXT: {{ $}} 78 ; CHECK-NEXT: [[COPY:%[0-9]+]]:g8rc_and_g8rc_nox0 = COPY $x8 79 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:g8rc_and_g8rc_nox0 = COPY $x7 80 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vrrc = COPY $v2 81 ; CHECK-NEXT: [[COPY3:%[0-9]+]]:f8rc = COPY $f2 82 ; CHECK-NEXT: [[COPY4:%[0-9]+]]:f8rc = COPY $f1 83 ; CHECK-NEXT: [[XSCVQPSWZ:%[0-9]+]]:vrrc = nofpexcept XSCVQPSWZ [[COPY2]] 84 ; CHECK-NEXT: [[COPY5:%[0-9]+]]:vslrc = COPY [[XSCVQPSWZ]] 85 ; CHECK-NEXT: [[COPY6:%[0-9]+]]:vsfrc = COPY [[COPY5]].sub_64 86 ; CHECK-NEXT: STIWX killed [[COPY6]], $zero8, [[COPY1]] 87 ; CHECK-NEXT: [[XSCVQPUWZ:%[0-9]+]]:vrrc = nofpexcept XSCVQPUWZ [[COPY2]] 88 ; CHECK-NEXT: [[COPY7:%[0-9]+]]:vslrc = COPY [[XSCVQPUWZ]] 89 ; CHECK-NEXT: [[COPY8:%[0-9]+]]:vsfrc = COPY [[COPY7]].sub_64 90 ; CHECK-NEXT: STIWX killed [[COPY8]], $zero8, [[COPY1]] 91 ; CHECK-NEXT: [[XSCVQPSDZ:%[0-9]+]]:vrrc = nofpexcept XSCVQPSDZ [[COPY2]] 92 ; CHECK-NEXT: [[MFVRD:%[0-9]+]]:g8rc = nofpexcept MFVRD killed [[XSCVQPSDZ]] 93 ; CHECK-NEXT: [[XSCVQPSDZ1:%[0-9]+]]:vrrc = nofpexcept XSCVQPSDZ [[COPY2]] 94 ; CHECK-NEXT: [[COPY9:%[0-9]+]]:vslrc = COPY [[XSCVQPSDZ1]] 95 ; CHECK-NEXT: [[COPY10:%[0-9]+]]:vfrc = COPY [[COPY9]].sub_64 96 ; CHECK-NEXT: STXSD killed [[COPY10]], 0, [[COPY]] 97 ; CHECK-NEXT: [[XSCVQPUDZ:%[0-9]+]]:vrrc = nofpexcept XSCVQPUDZ [[COPY2]] 98 ; CHECK-NEXT: [[MFVRD1:%[0-9]+]]:g8rc = nofpexcept MFVRD killed [[XSCVQPUDZ]] 99 ; CHECK-NEXT: [[XSCVQPUDZ1:%[0-9]+]]:vrrc = nofpexcept XSCVQPUDZ [[COPY2]] 100 ; CHECK-NEXT: [[COPY11:%[0-9]+]]:vslrc = COPY [[XSCVQPUDZ1]] 101 ; CHECK-NEXT: [[COPY12:%[0-9]+]]:vfrc = COPY [[COPY11]].sub_64 102 ; CHECK-NEXT: STXSD killed [[COPY12]], 0, [[COPY]] 103 ; CHECK-NEXT: [[MFFS:%[0-9]+]]:f8rc = MFFS implicit $rm 104 ; CHECK-NEXT: MTFSB1 31, implicit-def $rm, implicit-def $rm 105 ; CHECK-NEXT: MTFSB0 30, implicit-def $rm, implicit-def $rm 106 ; CHECK-NEXT: [[FADD:%[0-9]+]]:f8rc = nofpexcept FADD [[COPY3]], [[COPY4]], implicit $rm 107 ; CHECK-NEXT: MTFSFb 1, [[MFFS]], implicit-def $rm 108 ; CHECK-NEXT: [[XSCVDPSXWS:%[0-9]+]]:vsfrc = nofpexcept XSCVDPSXWS killed [[FADD]], implicit $rm 109 ; CHECK-NEXT: STIWX killed [[XSCVDPSXWS]], $zero8, [[COPY1]] 110 ; CHECK-NEXT: [[ADDIStocHA8_:%[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0 111 ; CHECK-NEXT: [[DFLOADf32_:%[0-9]+]]:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0, killed [[ADDIStocHA8_]] :: (load (s32) from constant-pool) 112 ; CHECK-NEXT: [[COPY13:%[0-9]+]]:f8rc = COPY [[DFLOADf32_]] 113 ; CHECK-NEXT: [[FCMPOD:%[0-9]+]]:crrc = FCMPOD [[COPY4]], [[COPY13]] 114 ; CHECK-NEXT: [[COPY14:%[0-9]+]]:crbitrc = COPY [[FCMPOD]].sub_eq 115 ; CHECK-NEXT: [[XXLXORdpz:%[0-9]+]]:f8rc = XXLXORdpz 116 ; CHECK-NEXT: [[FCMPOD1:%[0-9]+]]:crrc = FCMPOD [[COPY3]], [[XXLXORdpz]] 117 ; CHECK-NEXT: [[COPY15:%[0-9]+]]:crbitrc = COPY [[FCMPOD1]].sub_lt 118 ; CHECK-NEXT: [[CRAND:%[0-9]+]]:crbitrc = CRAND killed [[COPY14]], killed [[COPY15]] 119 ; CHECK-NEXT: [[COPY16:%[0-9]+]]:crbitrc = COPY [[FCMPOD]].sub_eq 120 ; CHECK-NEXT: [[COPY17:%[0-9]+]]:crbitrc = COPY [[FCMPOD]].sub_lt 121 ; CHECK-NEXT: [[CRANDC:%[0-9]+]]:crbitrc = CRANDC killed [[COPY17]], killed [[COPY16]] 122 ; CHECK-NEXT: [[CROR:%[0-9]+]]:crbitrc = CROR killed [[CRANDC]], killed [[CRAND]] 123 ; CHECK-NEXT: [[LIS:%[0-9]+]]:gprc_and_gprc_nor0 = LIS 32768 124 ; CHECK-NEXT: [[LI:%[0-9]+]]:gprc_and_gprc_nor0 = LI 0 125 ; CHECK-NEXT: [[ISEL:%[0-9]+]]:gprc = ISEL [[LI]], [[LIS]], [[CROR]] 126 ; CHECK-NEXT: BC [[CROR]], %bb.2 127 ; CHECK-NEXT: {{ $}} 128 ; CHECK-NEXT: bb.1.entry: 129 ; CHECK-NEXT: successors: %bb.2(0x80000000) 130 ; CHECK-NEXT: {{ $}} 131 ; CHECK-NEXT: bb.2.entry: 132 ; CHECK-NEXT: [[PHI:%[0-9]+]]:f8rc = PHI [[COPY13]], %bb.1, [[XXLXORdpz]], %bb.0 133 ; CHECK-NEXT: ADJCALLSTACKDOWN 32, 0, implicit-def dead $r1, implicit $r1 134 ; CHECK-NEXT: $f1 = COPY [[COPY4]] 135 ; CHECK-NEXT: $f2 = COPY [[COPY3]] 136 ; CHECK-NEXT: $f3 = COPY [[PHI]] 137 ; CHECK-NEXT: $f4 = COPY [[XXLXORdpz]] 138 ; CHECK-NEXT: BL8_NOP &__gcc_qsub, csr_ppc64_altivec, implicit-def dead $lr8, implicit $rm, implicit $f1, implicit $f2, implicit $f3, implicit $f4, implicit $x2, implicit-def $r1, implicit-def $f1, implicit-def $f2 139 ; CHECK-NEXT: ADJCALLSTACKUP 32, 0, implicit-def dead $r1, implicit $r1 140 ; CHECK-NEXT: [[COPY18:%[0-9]+]]:f8rc = COPY $f1 141 ; CHECK-NEXT: [[COPY19:%[0-9]+]]:f8rc = COPY $f2 142 ; CHECK-NEXT: [[MFFS1:%[0-9]+]]:f8rc = MFFS implicit $rm 143 ; CHECK-NEXT: MTFSB1 31, implicit-def $rm, implicit-def $rm 144 ; CHECK-NEXT: MTFSB0 30, implicit-def $rm, implicit-def $rm 145 ; CHECK-NEXT: [[FADD1:%[0-9]+]]:f8rc = nofpexcept FADD [[COPY19]], [[COPY18]], implicit $rm 146 ; CHECK-NEXT: MTFSFb 1, [[MFFS1]], implicit-def $rm 147 ; CHECK-NEXT: [[XSCVDPSXWS1:%[0-9]+]]:vsfrc = nofpexcept XSCVDPSXWS killed [[FADD1]], implicit $rm 148 ; CHECK-NEXT: [[MFVSRWZ:%[0-9]+]]:gprc = MFVSRWZ killed [[XSCVDPSXWS1]] 149 ; CHECK-NEXT: [[XOR:%[0-9]+]]:gprc = XOR killed [[MFVSRWZ]], killed [[ISEL]] 150 ; CHECK-NEXT: STW killed [[XOR]], 0, [[COPY1]] :: (volatile store (s32) into %ir.addr1) 151 ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm 152entry: 153 %conv1 = tail call i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128 %m, metadata !"fpexcept.ignore") 154 store volatile i32 %conv1, ptr %addr1, align 4 155 %conv2 = tail call i32 @llvm.experimental.constrained.fptoui.i32.f128(fp128 %m, metadata !"fpexcept.ignore") 156 store volatile i32 %conv2, ptr %addr1, align 4 157 %conv3 = tail call i64 @llvm.experimental.constrained.fptosi.i64.f128(fp128 %m, metadata !"fpexcept.ignore") 158 store volatile i64 %conv3, ptr %addr2, align 8 159 %conv4 = tail call i64 @llvm.experimental.constrained.fptoui.i64.f128(fp128 %m, metadata !"fpexcept.ignore") 160 store volatile i64 %conv4, ptr %addr2, align 8 161 162 %conv5 = tail call i32 @llvm.experimental.constrained.fptosi.i32.ppcf128(ppc_fp128 %p, metadata !"fpexcept.ignore") 163 store volatile i32 %conv5, ptr %addr1, align 4 164 %conv6 = tail call i32 @llvm.experimental.constrained.fptoui.i32.ppcf128(ppc_fp128 %p, metadata !"fpexcept.ignore") 165 store volatile i32 %conv6, ptr %addr1, align 4 166 ret void 167} 168 169; Verify nofpexcept is NOT set to constrained conversions 170define signext i32 @q_to_i32(fp128 %m) #0 { 171 ; CHECK-LABEL: name: q_to_i32 172 ; CHECK: bb.0.entry: 173 ; CHECK-NEXT: liveins: $v2 174 ; CHECK-NEXT: {{ $}} 175 ; CHECK-NEXT: [[COPY:%[0-9]+]]:vrrc = COPY $v2 176 ; CHECK-NEXT: [[XSCVQPSWZ:%[0-9]+]]:vrrc = XSCVQPSWZ [[COPY]] 177 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vslrc = COPY [[XSCVQPSWZ]] 178 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vfrc = COPY [[COPY1]].sub_64 179 ; CHECK-NEXT: [[MFVSRWZ:%[0-9]+]]:gprc = MFVSRWZ killed [[COPY2]] 180 ; CHECK-NEXT: [[EXTSW_32_64_:%[0-9]+]]:g8rc = EXTSW_32_64 killed [[MFVSRWZ]] 181 ; CHECK-NEXT: $x3 = COPY [[EXTSW_32_64_]] 182 ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $x3 183entry: 184 %conv = tail call i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128 %m, metadata !"fpexcept.strict") 185 ret i32 %conv 186} 187 188define i64 @q_to_i64(fp128 %m) #0 { 189 ; CHECK-LABEL: name: q_to_i64 190 ; CHECK: bb.0.entry: 191 ; CHECK-NEXT: liveins: $v2 192 ; CHECK-NEXT: {{ $}} 193 ; CHECK-NEXT: [[COPY:%[0-9]+]]:vrrc = COPY $v2 194 ; CHECK-NEXT: [[XSCVQPSDZ:%[0-9]+]]:vrrc = XSCVQPSDZ [[COPY]] 195 ; CHECK-NEXT: [[MFVRD:%[0-9]+]]:g8rc = MFVRD killed [[XSCVQPSDZ]] 196 ; CHECK-NEXT: $x3 = COPY [[MFVRD]] 197 ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $x3 198entry: 199 %conv = tail call i64 @llvm.experimental.constrained.fptosi.i64.f128(fp128 %m, metadata !"fpexcept.strict") 200 ret i64 %conv 201} 202 203define i64 @q_to_u64(fp128 %m) #0 { 204 ; CHECK-LABEL: name: q_to_u64 205 ; CHECK: bb.0.entry: 206 ; CHECK-NEXT: liveins: $v2 207 ; CHECK-NEXT: {{ $}} 208 ; CHECK-NEXT: [[COPY:%[0-9]+]]:vrrc = COPY $v2 209 ; CHECK-NEXT: [[XSCVQPUDZ:%[0-9]+]]:vrrc = XSCVQPUDZ [[COPY]] 210 ; CHECK-NEXT: [[MFVRD:%[0-9]+]]:g8rc = MFVRD killed [[XSCVQPUDZ]] 211 ; CHECK-NEXT: $x3 = COPY [[MFVRD]] 212 ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $x3 213entry: 214 %conv = tail call i64 @llvm.experimental.constrained.fptoui.i64.f128(fp128 %m, metadata !"fpexcept.strict") 215 ret i64 %conv 216} 217 218define zeroext i32 @q_to_u32(fp128 %m) #0 { 219 ; CHECK-LABEL: name: q_to_u32 220 ; CHECK: bb.0.entry: 221 ; CHECK-NEXT: liveins: $v2 222 ; CHECK-NEXT: {{ $}} 223 ; CHECK-NEXT: [[COPY:%[0-9]+]]:vrrc = COPY $v2 224 ; CHECK-NEXT: [[XSCVQPUWZ:%[0-9]+]]:vrrc = XSCVQPUWZ [[COPY]] 225 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vslrc = COPY [[XSCVQPUWZ]] 226 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vfrc = COPY [[COPY1]].sub_64 227 ; CHECK-NEXT: [[MFVSRWZ:%[0-9]+]]:gprc = MFVSRWZ killed [[COPY2]] 228 ; CHECK-NEXT: [[DEF:%[0-9]+]]:g8rc = IMPLICIT_DEF 229 ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:g8rc = INSERT_SUBREG [[DEF]], killed [[MFVSRWZ]], %subreg.sub_32 230 ; CHECK-NEXT: [[RLDICL:%[0-9]+]]:g8rc = RLDICL killed [[INSERT_SUBREG]], 0, 32 231 ; CHECK-NEXT: $x3 = COPY [[RLDICL]] 232 ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $x3 233entry: 234 %conv = tail call i32 @llvm.experimental.constrained.fptoui.i32.f128(fp128 %m, metadata !"fpexcept.strict") 235 ret i32 %conv 236} 237 238declare double @llvm.fabs.f64(double) 239 240declare i32 @llvm.experimental.constrained.fptosi.i32.f128(fp128, metadata) 241declare i64 @llvm.experimental.constrained.fptosi.i64.f128(fp128, metadata) 242declare i64 @llvm.experimental.constrained.fptoui.i64.f128(fp128, metadata) 243declare i32 @llvm.experimental.constrained.fptoui.i32.f128(fp128, metadata) 244declare i32 @llvm.experimental.constrained.fptosi.i32.ppcf128(ppc_fp128, metadata) 245declare i32 @llvm.experimental.constrained.fptoui.i32.ppcf128(ppc_fp128, metadata) 246 247attributes #0 = { strictfp } 248