1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s 2 3 ; Test that basic 32-bit floating-point comparison operations assemble as 4 ; expected. 5 6 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 7 target triple = "wasm32-unknown-unknown" 8 9 ; CHECK-LABEL: ord_f32: 10 ; CHECK-NEXT: .param f32, f32{{$}} 11 ; CHECK-NEXT: .result i32{{$}} 12 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 13 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 0{{$}} 14 ; CHECK-NEXT: f32.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 15 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 1{{$}} 16 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 1{{$}} 17 ; CHECK-NEXT: f32.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}} 18 ; CHECK-NEXT: i32.and $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}} 19 ; CHECK-NEXT: return $pop[[NUM2]]{{$}} 20 define i32 @ord_f32(float %x, float %y) { 21 %a = fcmp ord float %x, %y 22 %b = zext i1 %a to i32 23 ret i32 %b 24 } 25 26 ; CHECK-LABEL: uno_f32: 27 ; CHECK-NEXT: .param f32, f32{{$}} 28 ; CHECK-NEXT: .result i32{{$}} 29 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 30 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 0{{$}} 31 ; CHECK-NEXT: f32.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 32 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 1{{$}} 33 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 1{{$}} 34 ; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}} 35 ; CHECK-NEXT: i32.or $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}} 36 ; CHECK-NEXT: return $pop[[NUM2]]{{$}} 37 define i32 @uno_f32(float %x, float %y) { 38 %a = fcmp uno float %x, %y 39 %b = zext i1 %a to i32 40 ret i32 %b 41 } 42 43 ; CHECK-LABEL: oeq_f32: 44 ; CHECK-NEXT: .param f32, f32{{$}} 45 ; CHECK-NEXT: .result i32{{$}} 46 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 47 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 48 ; CHECK-NEXT: f32.eq $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 49 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 50 define i32 @oeq_f32(float %x, float %y) { 51 %a = fcmp oeq float %x, %y 52 %b = zext i1 %a to i32 53 ret i32 %b 54 } 55 56 ; CHECK-LABEL: une_f32: 57 ; CHECK: f32.ne $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 58 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 59 define i32 @une_f32(float %x, float %y) { 60 %a = fcmp une float %x, %y 61 %b = zext i1 %a to i32 62 ret i32 %b 63 } 64 65 ; CHECK-LABEL: olt_f32: 66 ; CHECK: f32.lt $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 67 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 68 define i32 @olt_f32(float %x, float %y) { 69 %a = fcmp olt float %x, %y 70 %b = zext i1 %a to i32 71 ret i32 %b 72 } 73 74 ; CHECK-LABEL: ole_f32: 75 ; CHECK: f32.le $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 76 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 77 define i32 @ole_f32(float %x, float %y) { 78 %a = fcmp ole float %x, %y 79 %b = zext i1 %a to i32 80 ret i32 %b 81 } 82 83 ; CHECK-LABEL: ogt_f32: 84 ; CHECK: f32.gt $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 85 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 86 define i32 @ogt_f32(float %x, float %y) { 87 %a = fcmp ogt float %x, %y 88 %b = zext i1 %a to i32 89 ret i32 %b 90 } 91 92 ; CHECK-LABEL: oge_f32: 93 ; CHECK: f32.ge $push[[NUM:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 94 ; CHECK-NEXT: return $pop[[NUM]]{{$}} 95 define i32 @oge_f32(float %x, float %y) { 96 %a = fcmp oge float %x, %y 97 %b = zext i1 %a to i32 98 ret i32 %b 99 } 100 101 ; Expanded comparisons, which also check for NaN. 102 ; These simply rely on SDAG's Expand cond code action. 103 104 ; CHECK-LABEL: ueq_f32: 105 ; CHECK-NEXT: .param f32, f32{{$}} 106 ; CHECK-NEXT: .result i32{{$}} 107 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 108 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 109 ; CHECK-NEXT: f32.eq $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 110 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 0{{$}} 111 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 0{{$}} 112 ; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}} 113 ; CHECK-NEXT: get_local $push[[L4:[0-9]+]]=, 1{{$}} 114 ; CHECK-NEXT: get_local $push[[L5:[0-9]+]]=, 1{{$}} 115 ; CHECK-NEXT: f32.ne $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 116 ; CHECK-NEXT: i32.or $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}} 117 ; CHECK-NEXT: i32.or $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}} 118 ; CHECK-NEXT: return $pop[[NUM4]]{{$}} 119 define i32 @ueq_f32(float %x, float %y) { 120 %a = fcmp ueq float %x, %y 121 %b = zext i1 %a to i32 122 ret i32 %b 123 } 124 125 ; CHECK-LABEL: one_f32: 126 ; CHECK-NEXT: .param f32, f32{{$}} 127 ; CHECK-NEXT: .result i32{{$}} 128 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 129 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 130 ; CHECK-NEXT: f32.ne $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 131 ; CHECK-NEXT: get_local $push[[L2:[0-9]+]]=, 0{{$}} 132 ; CHECK-NEXT: get_local $push[[L3:[0-9]+]]=, 0{{$}} 133 ; CHECK-NEXT: f32.eq $push[[NUM1:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}} 134 ; CHECK-NEXT: get_local $push[[L4:[0-9]+]]=, 1{{$}} 135 ; CHECK-NEXT: get_local $push[[L5:[0-9]+]]=, 1{{$}} 136 ; CHECK-NEXT: f32.eq $push[[NUM2:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 137 ; CHECK-NEXT: i32.and $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}} 138 ; CHECK-NEXT: i32.and $push[[NUM4:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM3]]{{$}} 139 ; CHECK-NEXT: return $pop[[NUM4]] 140 define i32 @one_f32(float %x, float %y) { 141 %a = fcmp one float %x, %y 142 %b = zext i1 %a to i32 143 ret i32 %b 144 } 145 146 ; CHECK-LABEL: ult_f32: 147 ; CHECK-NEXT: .param f32, f32{{$}} 148 ; CHECK-NEXT: .result i32{{$}} 149 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 150 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 151 ; CHECK-NEXT: f32.ge $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 152 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1 153 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}} 154 ; CHECK-NEXT: return $pop[[NUM2]]{{$}} 155 define i32 @ult_f32(float %x, float %y) { 156 %a = fcmp ult float %x, %y 157 %b = zext i1 %a to i32 158 ret i32 %b 159 } 160 161 ; CHECK-LABEL: ule_f32: 162 ; CHECK-NEXT: .param f32, f32{{$}} 163 ; CHECK-NEXT: .result i32{{$}} 164 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 165 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 166 ; CHECK-NEXT: f32.gt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 167 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1 168 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}} 169 ; CHECK-NEXT: return $pop[[NUM2]]{{$}} 170 define i32 @ule_f32(float %x, float %y) { 171 %a = fcmp ule float %x, %y 172 %b = zext i1 %a to i32 173 ret i32 %b 174 } 175 176 ; CHECK-LABEL: ugt_f32: 177 ; CHECK-NEXT: .param f32, f32{{$}} 178 ; CHECK-NEXT: .result i32{{$}} 179 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 180 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 181 ; CHECK-NEXT: f32.le $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 182 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1 183 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}} 184 ; CHECK-NEXT: return $pop[[NUM2]]{{$}} 185 define i32 @ugt_f32(float %x, float %y) { 186 %a = fcmp ugt float %x, %y 187 %b = zext i1 %a to i32 188 ret i32 %b 189 } 190 191 ; CHECK-LABEL: uge_f32: 192 ; CHECK-NEXT: .param f32, f32{{$}} 193 ; CHECK-NEXT: .result i32{{$}} 194 ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} 195 ; CHECK-NEXT: get_local $push[[L1:[0-9]+]]=, 1{{$}} 196 ; CHECK-NEXT: f32.lt $push[[NUM0:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 197 ; CHECK-NEXT: i32.const $push[[C0:[0-9]+]]=, 1 198 ; CHECK-NEXT: i32.xor $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[C0]]{{$}} 199 ; CHECK-NEXT: return $pop[[NUM2]]{{$}} 200 define i32 @uge_f32(float %x, float %y) { 201 %a = fcmp uge float %x, %y 202 %b = zext i1 %a to i32 203 ret i32 %b 204 } 205