1 ; RUN: llc < %s -mtriple=arm64-eabi -mcpu=cyclone -aarch64-neon-syntax=apple | FileCheck %s 2 ; rdar://10263824 3 4 define i1 @fcmp_float1(float %a) nounwind ssp { 5 entry: 6 ; CHECK-LABEL: @fcmp_float1 7 ; CHECK: fcmp s0, #0.0 8 ; CHECK: cset w0, ne 9 %cmp = fcmp une float %a, 0.000000e+00 10 ret i1 %cmp 11 } 12 13 define i1 @fcmp_float2(float %a, float %b) nounwind ssp { 14 entry: 15 ; CHECK-LABEL: @fcmp_float2 16 ; CHECK: fcmp s0, s1 17 ; CHECK: cset w0, ne 18 %cmp = fcmp une float %a, %b 19 ret i1 %cmp 20 } 21 22 define i1 @fcmp_double1(double %a) nounwind ssp { 23 entry: 24 ; CHECK-LABEL: @fcmp_double1 25 ; CHECK: fcmp d0, #0.0 26 ; CHECK: cset w0, ne 27 %cmp = fcmp une double %a, 0.000000e+00 28 ret i1 %cmp 29 } 30 31 define i1 @fcmp_double2(double %a, double %b) nounwind ssp { 32 entry: 33 ; CHECK-LABEL: @fcmp_double2 34 ; CHECK: fcmp d0, d1 35 ; CHECK: cset w0, ne 36 %cmp = fcmp une double %a, %b 37 ret i1 %cmp 38 } 39 40 ; Check each fcmp condition 41 define float @fcmp_oeq(float %a, float %b) nounwind ssp { 42 ; CHECK-LABEL: @fcmp_oeq 43 ; CHECK: fcmp s0, s1 44 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 45 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 46 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], eq 47 48 %cmp = fcmp oeq float %a, %b 49 %conv = uitofp i1 %cmp to float 50 ret float %conv 51 } 52 53 define float @fcmp_ogt(float %a, float %b) nounwind ssp { 54 ; CHECK-LABEL: @fcmp_ogt 55 ; CHECK: fcmp s0, s1 56 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 57 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 58 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], gt 59 60 %cmp = fcmp ogt float %a, %b 61 %conv = uitofp i1 %cmp to float 62 ret float %conv 63 } 64 65 define float @fcmp_oge(float %a, float %b) nounwind ssp { 66 ; CHECK-LABEL: @fcmp_oge 67 ; CHECK: fcmp s0, s1 68 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 69 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 70 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], ge 71 72 %cmp = fcmp oge float %a, %b 73 %conv = uitofp i1 %cmp to float 74 ret float %conv 75 } 76 77 define float @fcmp_olt(float %a, float %b) nounwind ssp { 78 ; CHECK-LABEL: @fcmp_olt 79 ; CHECK: fcmp s0, s1 80 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 81 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 82 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], mi 83 84 %cmp = fcmp olt float %a, %b 85 %conv = uitofp i1 %cmp to float 86 ret float %conv 87 } 88 89 define float @fcmp_ole(float %a, float %b) nounwind ssp { 90 ; CHECK-LABEL: @fcmp_ole 91 ; CHECK: fcmp s0, s1 92 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 93 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 94 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], ls 95 96 %cmp = fcmp ole float %a, %b 97 %conv = uitofp i1 %cmp to float 98 ret float %conv 99 } 100 101 define float @fcmp_ord(float %a, float %b) nounwind ssp { 102 ; CHECK-LABEL: @fcmp_ord 103 ; CHECK: fcmp s0, s1 104 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 105 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 106 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], vc 107 %cmp = fcmp ord float %a, %b 108 %conv = uitofp i1 %cmp to float 109 ret float %conv 110 } 111 112 define float @fcmp_uno(float %a, float %b) nounwind ssp { 113 ; CHECK-LABEL: @fcmp_uno 114 ; CHECK: fcmp s0, s1 115 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 116 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 117 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], vs 118 %cmp = fcmp uno float %a, %b 119 %conv = uitofp i1 %cmp to float 120 ret float %conv 121 } 122 123 define float @fcmp_ugt(float %a, float %b) nounwind ssp { 124 ; CHECK-LABEL: @fcmp_ugt 125 ; CHECK: fcmp s0, s1 126 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 127 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 128 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], hi 129 %cmp = fcmp ugt float %a, %b 130 %conv = uitofp i1 %cmp to float 131 ret float %conv 132 } 133 134 define float @fcmp_uge(float %a, float %b) nounwind ssp { 135 ; CHECK-LABEL: @fcmp_uge 136 ; CHECK: fcmp s0, s1 137 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 138 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 139 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], pl 140 %cmp = fcmp uge float %a, %b 141 %conv = uitofp i1 %cmp to float 142 ret float %conv 143 } 144 145 define float @fcmp_ult(float %a, float %b) nounwind ssp { 146 ; CHECK-LABEL: @fcmp_ult 147 ; CHECK: fcmp s0, s1 148 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 149 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 150 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], lt 151 %cmp = fcmp ult float %a, %b 152 %conv = uitofp i1 %cmp to float 153 ret float %conv 154 } 155 156 define float @fcmp_ule(float %a, float %b) nounwind ssp { 157 ; CHECK-LABEL: @fcmp_ule 158 ; CHECK: fcmp s0, s1 159 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 160 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 161 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], le 162 %cmp = fcmp ule float %a, %b 163 %conv = uitofp i1 %cmp to float 164 ret float %conv 165 } 166 167 define float @fcmp_une(float %a, float %b) nounwind ssp { 168 ; CHECK-LABEL: @fcmp_une 169 ; CHECK: fcmp s0, s1 170 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 171 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 172 ; CHECK: fcsel s0, s[[ONE]], s[[ZERO]], ne 173 %cmp = fcmp une float %a, %b 174 %conv = uitofp i1 %cmp to float 175 ret float %conv 176 } 177 178 ; Possible opportunity for improvement. See comment in 179 ; ARM64TargetLowering::LowerSETCC() 180 define float @fcmp_one(float %a, float %b) nounwind ssp { 181 ; CHECK-LABEL: @fcmp_one 182 ; fcmp s0, s1 183 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 184 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 185 ; CHECK: fcsel [[TMP:s[0-9]+]], s[[ONE]], s[[ZERO]], mi 186 ; CHECK: fcsel s0, s[[ONE]], [[TMP]], gt 187 %cmp = fcmp one float %a, %b 188 %conv = uitofp i1 %cmp to float 189 ret float %conv 190 } 191 192 ; Possible opportunity for improvement. See comment in 193 ; ARM64TargetLowering::LowerSETCC() 194 define float @fcmp_ueq(float %a, float %b) nounwind ssp { 195 ; CHECK-LABEL: @fcmp_ueq 196 ; CHECK: fcmp s0, s1 197 ; CHECK-DAG: fmov s[[ZERO:[0-9]+]], wzr 198 ; CHECK-DAG: fmov s[[ONE:[0-9]+]], #1.0 199 ; CHECK: fcsel [[TMP:s[0-9]+]], s[[ONE]], s[[ZERO]], eq 200 ; CHECK: fcsel s0, s[[ONE]], [[TMP]], vs 201 %cmp = fcmp ueq float %a, %b 202 %conv = uitofp i1 %cmp to float 203 ret float %conv 204 } 205