llvm.org GIT mirror llvm / e9e0d4f
[ARM] GlobalISel: Legalize G_FCMP for s32 This covers both hard and soft float. Hard float is easy, since it's just Legal. Soft float is more involved, because there are several different ways to handle it based on the predicate: one and ueq need not only one, but two libcalls to get a result. Furthermore, we have large differences between the values returned by the AEABI and GNU functions. AEABI functions return a nice 1 or 0 representing true and respectively false. GNU functions generally return a value that needs to be compared against 0 (e.g. for ogt, the value returned by the libcall is > 0 for true). We could introduce redundant comparisons for AEABI as well, but they don't seem easy to remove afterwards, so we do different processing based on whether or not the result really needs to be compared against something (and just truncate if it doesn't). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307243 91177308-0d34-0410-b5e6-96231b3b80d8 Diana Picus 3 years ago
4 changed file(s) with 819 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
105105 auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
106106 auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
107107 const char *Name = TLI.getLibcallName(Libcall);
108
108109 MIRBuilder.getMF().getFrameInfo().setHasCalls(true);
109110 if (!CLI.lowerCall(MIRBuilder, TLI.getLibcallCallingConv(Libcall),
110111 MachineOperand::CreateES(Name), Result, Args))
111112 return LegalizerHelper::UnableToLegalize;
113
112114 return LegalizerHelper::Legalized;
113115 }
114116
103103
104104 setAction({G_LOAD, s64}, Legal);
105105 setAction({G_STORE, s64}, Legal);
106
107 setAction({G_FCMP, s1}, Legal);
108 setAction({G_FCMP, 1, s32}, Legal);
106109 } else {
107110 for (auto Ty : {s32, s64})
108111 setAction({G_FADD, Ty}, Libcall);
112
113 setAction({G_FCMP, s1}, Legal);
114 setAction({G_FCMP, 1, s32}, Custom);
115
116 if (AEABI(ST))
117 setFCmpLibcallsAEABI();
118 else
119 setFCmpLibcallsGNU();
109120 }
110121
111122 for (unsigned Op : {G_FREM, G_FPOW})
113124 setAction({Op, Ty}, Libcall);
114125
115126 computeTables();
127 }
128
129 void ARMLegalizerInfo::setFCmpLibcallsAEABI() {
130 // FCMP_TRUE and FCMP_FALSE don't need libcalls, they should be
131 // default-initialized.
132 FCmp32Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
133 FCmp32Libcalls[CmpInst::FCMP_OEQ] = {
134 {RTLIB::OEQ_F32, CmpInst::BAD_ICMP_PREDICATE}};
135 FCmp32Libcalls[CmpInst::FCMP_OGE] = {
136 {RTLIB::OGE_F32, CmpInst::BAD_ICMP_PREDICATE}};
137 FCmp32Libcalls[CmpInst::FCMP_OGT] = {
138 {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE}};
139 FCmp32Libcalls[CmpInst::FCMP_OLE] = {
140 {RTLIB::OLE_F32, CmpInst::BAD_ICMP_PREDICATE}};
141 FCmp32Libcalls[CmpInst::FCMP_OLT] = {
142 {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}};
143 FCmp32Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F32, CmpInst::ICMP_EQ}};
144 FCmp32Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F32, CmpInst::ICMP_EQ}};
145 FCmp32Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F32, CmpInst::ICMP_EQ}};
146 FCmp32Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F32, CmpInst::ICMP_EQ}};
147 FCmp32Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F32, CmpInst::ICMP_EQ}};
148 FCmp32Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F32, CmpInst::ICMP_EQ}};
149 FCmp32Libcalls[CmpInst::FCMP_UNO] = {
150 {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}};
151 FCmp32Libcalls[CmpInst::FCMP_ONE] = {
152 {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE},
153 {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}};
154 FCmp32Libcalls[CmpInst::FCMP_UEQ] = {
155 {RTLIB::OEQ_F32, CmpInst::BAD_ICMP_PREDICATE},
156 {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}};
157 }
158
159 void ARMLegalizerInfo::setFCmpLibcallsGNU() {
160 // FCMP_TRUE and FCMP_FALSE don't need libcalls, they should be
161 // default-initialized.
162 FCmp32Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
163 FCmp32Libcalls[CmpInst::FCMP_OEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ}};
164 FCmp32Libcalls[CmpInst::FCMP_OGE] = {{RTLIB::OGE_F32, CmpInst::ICMP_SGE}};
165 FCmp32Libcalls[CmpInst::FCMP_OGT] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT}};
166 FCmp32Libcalls[CmpInst::FCMP_OLE] = {{RTLIB::OLE_F32, CmpInst::ICMP_SLE}};
167 FCmp32Libcalls[CmpInst::FCMP_OLT] = {{RTLIB::OLT_F32, CmpInst::ICMP_SLT}};
168 FCmp32Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F32, CmpInst::ICMP_EQ}};
169 FCmp32Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F32, CmpInst::ICMP_SGE}};
170 FCmp32Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F32, CmpInst::ICMP_SGT}};
171 FCmp32Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SLE}};
172 FCmp32Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F32, CmpInst::ICMP_SLT}};
173 FCmp32Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F32, CmpInst::ICMP_NE}};
174 FCmp32Libcalls[CmpInst::FCMP_UNO] = {{RTLIB::UO_F32, CmpInst::ICMP_NE}};
175 FCmp32Libcalls[CmpInst::FCMP_ONE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT},
176 {RTLIB::OLT_F32, CmpInst::ICMP_SLT}};
177 FCmp32Libcalls[CmpInst::FCMP_UEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ},
178 {RTLIB::UO_F32, CmpInst::ICMP_NE}};
179 }
180
181 ARMLegalizerInfo::FCmpLibcallsList
182 ARMLegalizerInfo::getFCmpLibcalls(CmpInst::Predicate Predicate) const {
183 assert(CmpInst::isFPPredicate(Predicate) && "Unsupported FCmp predicate");
184 return FCmp32Libcalls[Predicate];
116185 }
117186
118187 bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI,
155224 MIRBuilder.buildUnmerge(
156225 {MRI.createGenericVirtualRegister(LLT::scalar(32)), OriginalResult},
157226 RetVal);
158
227 break;
228 }
229 case G_FCMP: {
230 assert(MRI.getType(MI.getOperand(2).getReg()).getSizeInBits() == 32 &&
231 "Unsupported size for FCMP");
232 assert(MRI.getType(MI.getOperand(3).getReg()).getSizeInBits() == 32 &&
233 "Unsupported size for FCMP");
234
235 auto OriginalResult = MI.getOperand(0).getReg();
236 auto Predicate =
237 static_cast(MI.getOperand(1).getPredicate());
238 auto Libcalls = getFCmpLibcalls(Predicate);
239
240 if (Libcalls.empty()) {
241 assert((Predicate == CmpInst::FCMP_TRUE ||
242 Predicate == CmpInst::FCMP_FALSE) &&
243 "Predicate needs libcalls, but none specified");
244 MIRBuilder.buildConstant(OriginalResult,
245 Predicate == CmpInst::FCMP_TRUE ? 1 : 0);
246 return true;
247 }
248
249 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
250 auto *ArgTy = Type::getFloatTy(Ctx);
251 auto *RetTy = Type::getInt32Ty(Ctx);
252
253 SmallVector Results;
254 for (auto Libcall : Libcalls) {
255 auto LibcallResult = MRI.createGenericVirtualRegister(LLT::scalar(32));
256 auto Status =
257 createLibcall(MIRBuilder, Libcall.LibcallID, {LibcallResult, RetTy},
258 {{MI.getOperand(2).getReg(), ArgTy},
259 {MI.getOperand(3).getReg(), ArgTy}});
260
261 if (Status != LegalizerHelper::Legalized)
262 return false;
263
264 auto ProcessedResult =
265 Libcalls.size() == 1
266 ? OriginalResult
267 : MRI.createGenericVirtualRegister(MRI.getType(OriginalResult));
268
269 // We have a result, but we need to transform it into a proper 1-bit 0 or
270 // 1, taking into account the different peculiarities of the values
271 // returned by the comparison functions.
272 CmpInst::Predicate ResultPred = Libcall.Predicate;
273 if (ResultPred == CmpInst::BAD_ICMP_PREDICATE) {
274 // We have a nice 0 or 1, and we just need to truncate it back to 1 bit
275 // to keep the types consistent.
276 MIRBuilder.buildTrunc(ProcessedResult, LibcallResult);
277 } else {
278 // We need to compare against 0.
279 assert(CmpInst::isIntPredicate(ResultPred) && "Unsupported predicate");
280 auto Zero = MRI.createGenericVirtualRegister(LLT::scalar(32));
281 MIRBuilder.buildConstant(Zero, 0);
282 MIRBuilder.buildICmp(ResultPred, ProcessedResult, LibcallResult, Zero);
283 }
284 Results.push_back(ProcessedResult);
285 }
286
287 if (Results.size() != 1) {
288 assert(Results.size() == 2 && "Unexpected number of results");
289 MIRBuilder.buildOr(OriginalResult, Results[0], Results[1]);
290 }
159291 break;
160292 }
161293 }
1313 #ifndef LLVM_LIB_TARGET_ARM_ARMMACHINELEGALIZER_H
1414 #define LLVM_LIB_TARGET_ARM_ARMMACHINELEGALIZER_H
1515
16 #include "llvm/ADT/IndexedMap.h"
1617 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
18 #include "llvm/CodeGen/RuntimeLibcalls.h"
19 #include "llvm/IR/Instructions.h"
1720
1821 namespace llvm {
1922
2629
2730 bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI,
2831 MachineIRBuilder &MIRBuilder) const override;
32
33 private:
34 void setFCmpLibcallsGNU();
35 void setFCmpLibcallsAEABI();
36
37 struct FCmpLibcallInfo {
38 // Which libcall this is.
39 RTLIB::Libcall LibcallID;
40
41 // The predicate to be used when comparing the value returned by the
42 // function with a relevant constant (currently hard-coded to zero). This is
43 // necessary because often the libcall will return e.g. a value greater than
44 // 0 to represent 'true' and anything negative to represent 'false', or
45 // maybe 0 to represent 'true' and non-zero for 'false'. If no comparison is
46 // needed, this should be CmpInst::BAD_ICMP_PREDICATE.
47 CmpInst::Predicate Predicate;
48 };
49 using FCmpLibcallsList = SmallVector;
50
51 // Map from each FCmp predicate to the corresponding libcall infos. A FCmp
52 // instruction may be lowered to one or two libcalls, which is why we need a
53 // list. If two libcalls are needed, their results will be OR'ed.
54 using FCmpLibcallsMapTy = IndexedMap;
55
56 FCmpLibcallsMapTy FCmp32Libcalls;
57
58 FCmpLibcallsList getFCmpLibcalls(CmpInst::Predicate) const;
2959 };
3060 } // End llvm namespace.
3161 #endif
99
1010 define void @test_fadd_float() { ret void }
1111 define void @test_fadd_double() { ret void }
12
13 define void @test_fcmp_true_s32() { ret void }
14 define void @test_fcmp_false_s32() { ret void }
15
16 define void @test_fcmp_oeq_s32() { ret void }
17 define void @test_fcmp_ogt_s32() { ret void }
18 define void @test_fcmp_oge_s32() { ret void }
19 define void @test_fcmp_olt_s32() { ret void }
20 define void @test_fcmp_ole_s32() { ret void }
21 define void @test_fcmp_ord_s32() { ret void }
22 define void @test_fcmp_ugt_s32() { ret void }
23 define void @test_fcmp_uge_s32() { ret void }
24 define void @test_fcmp_ult_s32() { ret void }
25 define void @test_fcmp_ule_s32() { ret void }
26 define void @test_fcmp_une_s32() { ret void }
27 define void @test_fcmp_uno_s32() { ret void }
28
29 define void @test_fcmp_one_s32() { ret void }
30 define void @test_fcmp_ueq_s32() { ret void }
1231 ...
1332 ---
1433 name: test_frem_float
275294 %r1 = COPY %8(s32)
276295 BX_RET 14, _, implicit %r0, implicit %r1
277296 ...
297 ---
298 name: test_fcmp_true_s32
299 # CHECK-LABEL: name: test_fcmp_true_s32
300 legalized: false
301 # CHECK: legalized: true
302 regBankSelected: false
303 selected: false
304 tracksRegLiveness: true
305 registers:
306 - { id: 0, class: _ }
307 - { id: 1, class: _ }
308 - { id: 2, class: _ }
309 - { id: 3, class: _ }
310 body: |
311 bb.0:
312 liveins: %r0, %r1
313
314 %0(s32) = COPY %r0
315 %1(s32) = COPY %r1
316 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
317 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
318 %2(s1) = G_FCMP floatpred(true), %0(s32), %1
319 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(true), [[X]](s32), [[Y]]
320 ; SOFT: [[REXT:%[0-9]+]](s32) = G_CONSTANT i32 -1
321 ; SOFT: [[R:%[0-9]+]](s1) = G_TRUNC [[REXT]](s32)
322 %3(s32) = G_ZEXT %2(s1)
323 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
324 %r0 = COPY %3(s32)
325 ; CHECK: %r0 = COPY [[REXT]]
326 BX_RET 14, _, implicit %r0
327 ...
328 ---
329 name: test_fcmp_false_s32
330 # CHECK-LABEL: name: test_fcmp_false_s32
331 legalized: false
332 # CHECK: legalized: true
333 regBankSelected: false
334 selected: false
335 tracksRegLiveness: true
336 registers:
337 - { id: 0, class: _ }
338 - { id: 1, class: _ }
339 - { id: 2, class: _ }
340 - { id: 3, class: _ }
341 body: |
342 bb.0:
343 liveins: %r0, %r1
344
345 %0(s32) = COPY %r0
346 %1(s32) = COPY %r1
347 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
348 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
349 %2(s1) = G_FCMP floatpred(false), %0(s32), %1
350 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(false), [[X]](s32), [[Y]]
351 ; SOFT: [[REXT:%[0-9]+]](s32) = G_CONSTANT i32 0
352 ; SOFT: [[R:%[0-9]+]](s1) = G_TRUNC [[REXT]](s32)
353 %3(s32) = G_ZEXT %2(s1)
354 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
355 %r0 = COPY %3(s32)
356 ; CHECK: %r0 = COPY [[REXT]]
357 BX_RET 14, _, implicit %r0
358 ...
359 ---
360 name: test_fcmp_oeq_s32
361 # CHECK-LABEL: name: test_fcmp_oeq_s32
362 legalized: false
363 # CHECK: legalized: true
364 regBankSelected: false
365 selected: false
366 tracksRegLiveness: true
367 registers:
368 - { id: 0, class: _ }
369 - { id: 1, class: _ }
370 - { id: 2, class: _ }
371 - { id: 3, class: _ }
372 body: |
373 bb.0:
374 liveins: %r0, %r1
375
376 %0(s32) = COPY %r0
377 %1(s32) = COPY %r1
378 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
379 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
380 %2(s1) = G_FCMP floatpred(oeq), %0(s32), %1
381 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(oeq), [[X]](s32), [[Y]]
382 ; SOFT: ADJCALLSTACKDOWN
383 ; SOFT-DAG: %r0 = COPY [[X]]
384 ; SOFT-DAG: %r1 = COPY [[Y]]
385 ; SOFT-AEABI: BLX $__aeabi_fcmpeq, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
386 ; SOFT-DEFAULT: BLX $__eqsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
387 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
388 ; SOFT: ADJCALLSTACKUP
389 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_TRUNC [[RET]](s32)
390 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
391 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(eq), [[RET]](s32), [[ZERO]]
392 %3(s32) = G_ZEXT %2(s1)
393 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
394 %r0 = COPY %3(s32)
395 ; CHECK: %r0 = COPY [[REXT]]
396 BX_RET 14, _, implicit %r0
397 ...
398 ---
399 name: test_fcmp_ogt_s32
400 # CHECK-LABEL: name: test_fcmp_ogt_s32
401 legalized: false
402 # CHECK: legalized: true
403 regBankSelected: false
404 selected: false
405 tracksRegLiveness: true
406 registers:
407 - { id: 0, class: _ }
408 - { id: 1, class: _ }
409 - { id: 2, class: _ }
410 - { id: 3, class: _ }
411 body: |
412 bb.0:
413 liveins: %r0, %r1
414
415 %0(s32) = COPY %r0
416 %1(s32) = COPY %r1
417 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
418 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
419 %2(s1) = G_FCMP floatpred(ogt), %0(s32), %1
420 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(ogt), [[X]](s32), [[Y]]
421 ; SOFT: ADJCALLSTACKDOWN
422 ; SOFT-DAG: %r0 = COPY [[X]]
423 ; SOFT-DAG: %r1 = COPY [[Y]]
424 ; SOFT-AEABI: BLX $__aeabi_fcmpgt, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
425 ; SOFT-DEFAULT: BLX $__gtsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
426 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
427 ; SOFT: ADJCALLSTACKUP
428 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_TRUNC [[RET]](s32)
429 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
430 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(sgt), [[RET]](s32), [[ZERO]]
431 %3(s32) = G_ZEXT %2(s1)
432 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
433 %r0 = COPY %3(s32)
434 ; CHECK: %r0 = COPY [[REXT]]
435 BX_RET 14, _, implicit %r0
436 ...
437 ---
438 name: test_fcmp_oge_s32
439 # CHECK-LABEL: name: test_fcmp_oge_s32
440 legalized: false
441 # CHECK: legalized: true
442 regBankSelected: false
443 selected: false
444 tracksRegLiveness: true
445 registers:
446 - { id: 0, class: _ }
447 - { id: 1, class: _ }
448 - { id: 2, class: _ }
449 - { id: 3, class: _ }
450 body: |
451 bb.0:
452 liveins: %r0, %r1
453
454 %0(s32) = COPY %r0
455 %1(s32) = COPY %r1
456 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
457 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
458 %2(s1) = G_FCMP floatpred(oge), %0(s32), %1
459 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(oge), [[X]](s32), [[Y]]
460 ; SOFT: ADJCALLSTACKDOWN
461 ; SOFT-DAG: %r0 = COPY [[X]]
462 ; SOFT-DAG: %r1 = COPY [[Y]]
463 ; SOFT-AEABI: BLX $__aeabi_fcmpge, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
464 ; SOFT-DEFAULT: BLX $__gesf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
465 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
466 ; SOFT: ADJCALLSTACKUP
467 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_TRUNC [[RET]](s32)
468 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
469 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(sge), [[RET]](s32), [[ZERO]]
470 %3(s32) = G_ZEXT %2(s1)
471 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
472 %r0 = COPY %3(s32)
473 ; CHECK: %r0 = COPY [[REXT]]
474 BX_RET 14, _, implicit %r0
475 ...
476 ---
477 name: test_fcmp_olt_s32
478 # CHECK-LABEL: name: test_fcmp_olt_s32
479 legalized: false
480 # CHECK: legalized: true
481 regBankSelected: false
482 selected: false
483 tracksRegLiveness: true
484 registers:
485 - { id: 0, class: _ }
486 - { id: 1, class: _ }
487 - { id: 2, class: _ }
488 - { id: 3, class: _ }
489 body: |
490 bb.0:
491 liveins: %r0, %r1
492
493 %0(s32) = COPY %r0
494 %1(s32) = COPY %r1
495 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
496 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
497 %2(s1) = G_FCMP floatpred(olt), %0(s32), %1
498 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(olt), [[X]](s32), [[Y]]
499 ; SOFT: ADJCALLSTACKDOWN
500 ; SOFT-DAG: %r0 = COPY [[X]]
501 ; SOFT-DAG: %r1 = COPY [[Y]]
502 ; SOFT-AEABI: BLX $__aeabi_fcmplt, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
503 ; SOFT-DEFAULT: BLX $__ltsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
504 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
505 ; SOFT: ADJCALLSTACKUP
506 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_TRUNC [[RET]](s32)
507 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
508 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(slt), [[RET]](s32), [[ZERO]]
509 %3(s32) = G_ZEXT %2(s1)
510 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
511 %r0 = COPY %3(s32)
512 ; CHECK: %r0 = COPY [[REXT]]
513 BX_RET 14, _, implicit %r0
514 ...
515 ---
516 name: test_fcmp_ole_s32
517 # CHECK-LABEL: name: test_fcmp_ole_s32
518 legalized: false
519 # CHECK: legalized: true
520 regBankSelected: false
521 selected: false
522 tracksRegLiveness: true
523 registers:
524 - { id: 0, class: _ }
525 - { id: 1, class: _ }
526 - { id: 2, class: _ }
527 - { id: 3, class: _ }
528 body: |
529 bb.0:
530 liveins: %r0, %r1
531
532 %0(s32) = COPY %r0
533 %1(s32) = COPY %r1
534 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
535 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
536 %2(s1) = G_FCMP floatpred(ole), %0(s32), %1
537 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(ole), [[X]](s32), [[Y]]
538 ; SOFT: ADJCALLSTACKDOWN
539 ; SOFT-DAG: %r0 = COPY [[X]]
540 ; SOFT-DAG: %r1 = COPY [[Y]]
541 ; SOFT-AEABI: BLX $__aeabi_fcmple, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
542 ; SOFT-DEFAULT: BLX $__lesf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
543 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
544 ; SOFT: ADJCALLSTACKUP
545 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_TRUNC [[RET]](s32)
546 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
547 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(sle), [[RET]](s32), [[ZERO]]
548 %3(s32) = G_ZEXT %2(s1)
549 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
550 %r0 = COPY %3(s32)
551 ; CHECK: %r0 = COPY [[REXT]]
552 BX_RET 14, _, implicit %r0
553 ...
554 ---
555 name: test_fcmp_ord_s32
556 # CHECK-LABEL: name: test_fcmp_ord_s32
557 legalized: false
558 # CHECK: legalized: true
559 regBankSelected: false
560 selected: false
561 tracksRegLiveness: true
562 registers:
563 - { id: 0, class: _ }
564 - { id: 1, class: _ }
565 - { id: 2, class: _ }
566 - { id: 3, class: _ }
567 body: |
568 bb.0:
569 liveins: %r0, %r1
570
571 %0(s32) = COPY %r0
572 %1(s32) = COPY %r1
573 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
574 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
575 %2(s1) = G_FCMP floatpred(ord), %0(s32), %1
576 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(ord), [[X]](s32), [[Y]]
577 ; SOFT: ADJCALLSTACKDOWN
578 ; SOFT-DAG: %r0 = COPY [[X]]
579 ; SOFT-DAG: %r1 = COPY [[Y]]
580 ; SOFT-AEABI: BLX $__aeabi_fcmpun, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
581 ; SOFT-DEFAULT: BLX $__unordsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
582 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
583 ; SOFT: ADJCALLSTACKUP
584 ; SOFT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
585 ; SOFT: [[R:%[0-9]+]](s1) = G_ICMP intpred(eq), [[RET]](s32), [[ZERO]]
586 %3(s32) = G_ZEXT %2(s1)
587 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
588 %r0 = COPY %3(s32)
589 ; CHECK: %r0 = COPY [[REXT]]
590 BX_RET 14, _, implicit %r0
591 ...
592 ---
593 name: test_fcmp_ugt_s32
594 # CHECK-LABEL: name: test_fcmp_ugt_s32
595 legalized: false
596 # CHECK: legalized: true
597 regBankSelected: false
598 selected: false
599 tracksRegLiveness: true
600 registers:
601 - { id: 0, class: _ }
602 - { id: 1, class: _ }
603 - { id: 2, class: _ }
604 - { id: 3, class: _ }
605 body: |
606 bb.0:
607 liveins: %r0, %r1
608
609 %0(s32) = COPY %r0
610 %1(s32) = COPY %r1
611 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
612 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
613 %2(s1) = G_FCMP floatpred(ugt), %0(s32), %1
614 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(ugt), [[X]](s32), [[Y]]
615 ; SOFT: ADJCALLSTACKDOWN
616 ; SOFT-DAG: %r0 = COPY [[X]]
617 ; SOFT-DAG: %r1 = COPY [[Y]]
618 ; SOFT-AEABI: BLX $__aeabi_fcmple, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
619 ; SOFT-DEFAULT: BLX $__lesf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
620 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
621 ; SOFT: ADJCALLSTACKUP
622 ; SOFT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
623 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_ICMP intpred(eq), [[RET]](s32), [[ZERO]]
624 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(sgt), [[RET]](s32), [[ZERO]]
625 %3(s32) = G_ZEXT %2(s1)
626 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
627 %r0 = COPY %3(s32)
628 ; CHECK: %r0 = COPY [[REXT]]
629 BX_RET 14, _, implicit %r0
630 ...
631 ---
632 name: test_fcmp_uge_s32
633 # CHECK-LABEL: name: test_fcmp_uge_s32
634 legalized: false
635 # CHECK: legalized: true
636 regBankSelected: false
637 selected: false
638 tracksRegLiveness: true
639 registers:
640 - { id: 0, class: _ }
641 - { id: 1, class: _ }
642 - { id: 2, class: _ }
643 - { id: 3, class: _ }
644 body: |
645 bb.0:
646 liveins: %r0, %r1
647
648 %0(s32) = COPY %r0
649 %1(s32) = COPY %r1
650 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
651 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
652 %2(s1) = G_FCMP floatpred(uge), %0(s32), %1
653 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(uge), [[X]](s32), [[Y]]
654 ; SOFT: ADJCALLSTACKDOWN
655 ; SOFT-DAG: %r0 = COPY [[X]]
656 ; SOFT-DAG: %r1 = COPY [[Y]]
657 ; SOFT-AEABI: BLX $__aeabi_fcmplt, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
658 ; SOFT-DEFAULT: BLX $__ltsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
659 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
660 ; SOFT: ADJCALLSTACKUP
661 ; SOFT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
662 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_ICMP intpred(eq), [[RET]](s32), [[ZERO]]
663 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(sge), [[RET]](s32), [[ZERO]]
664 %3(s32) = G_ZEXT %2(s1)
665 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
666 %r0 = COPY %3(s32)
667 ; CHECK: %r0 = COPY [[REXT]]
668 BX_RET 14, _, implicit %r0
669 ...
670 ---
671 name: test_fcmp_ult_s32
672 # CHECK-LABEL: name: test_fcmp_ult_s32
673 legalized: false
674 # CHECK: legalized: true
675 regBankSelected: false
676 selected: false
677 tracksRegLiveness: true
678 registers:
679 - { id: 0, class: _ }
680 - { id: 1, class: _ }
681 - { id: 2, class: _ }
682 - { id: 3, class: _ }
683 body: |
684 bb.0:
685 liveins: %r0, %r1
686
687 %0(s32) = COPY %r0
688 %1(s32) = COPY %r1
689 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
690 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
691 %2(s1) = G_FCMP floatpred(ult), %0(s32), %1
692 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(ult), [[X]](s32), [[Y]]
693 ; SOFT: ADJCALLSTACKDOWN
694 ; SOFT-DAG: %r0 = COPY [[X]]
695 ; SOFT-DAG: %r1 = COPY [[Y]]
696 ; SOFT-AEABI: BLX $__aeabi_fcmpge, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
697 ; SOFT-DEFAULT: BLX $__gesf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
698 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
699 ; SOFT: ADJCALLSTACKUP
700 ; SOFT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
701 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_ICMP intpred(eq), [[RET]](s32), [[ZERO]]
702 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(slt), [[RET]](s32), [[ZERO]]
703 %3(s32) = G_ZEXT %2(s1)
704 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
705 %r0 = COPY %3(s32)
706 ; CHECK: %r0 = COPY [[REXT]]
707 BX_RET 14, _, implicit %r0
708 ...
709 ---
710 name: test_fcmp_ule_s32
711 # CHECK-LABEL: name: test_fcmp_ule_s32
712 legalized: false
713 # CHECK: legalized: true
714 regBankSelected: false
715 selected: false
716 tracksRegLiveness: true
717 registers:
718 - { id: 0, class: _ }
719 - { id: 1, class: _ }
720 - { id: 2, class: _ }
721 - { id: 3, class: _ }
722 body: |
723 bb.0:
724 liveins: %r0, %r1
725
726 %0(s32) = COPY %r0
727 %1(s32) = COPY %r1
728 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
729 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
730 %2(s1) = G_FCMP floatpred(ule), %0(s32), %1
731 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(ule), [[X]](s32), [[Y]]
732 ; SOFT: ADJCALLSTACKDOWN
733 ; SOFT-DAG: %r0 = COPY [[X]]
734 ; SOFT-DAG: %r1 = COPY [[Y]]
735 ; SOFT-AEABI: BLX $__aeabi_fcmpgt, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
736 ; SOFT-DEFAULT: BLX $__gtsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
737 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
738 ; SOFT: ADJCALLSTACKUP
739 ; SOFT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
740 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_ICMP intpred(eq), [[RET]](s32), [[ZERO]]
741 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(sle), [[RET]](s32), [[ZERO]]
742 %3(s32) = G_ZEXT %2(s1)
743 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
744 %r0 = COPY %3(s32)
745 ; CHECK: %r0 = COPY [[REXT]]
746 BX_RET 14, _, implicit %r0
747 ...
748 ---
749 name: test_fcmp_une_s32
750 # CHECK-LABEL: name: test_fcmp_une_s32
751 legalized: false
752 # CHECK: legalized: true
753 regBankSelected: false
754 selected: false
755 tracksRegLiveness: true
756 registers:
757 - { id: 0, class: _ }
758 - { id: 1, class: _ }
759 - { id: 2, class: _ }
760 - { id: 3, class: _ }
761 body: |
762 bb.0:
763 liveins: %r0, %r1
764
765 %0(s32) = COPY %r0
766 %1(s32) = COPY %r1
767 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
768 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
769 %2(s1) = G_FCMP floatpred(une), %0(s32), %1
770 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(une), [[X]](s32), [[Y]]
771 ; SOFT: ADJCALLSTACKDOWN
772 ; SOFT-DAG: %r0 = COPY [[X]]
773 ; SOFT-DAG: %r1 = COPY [[Y]]
774 ; SOFT-AEABI: BLX $__aeabi_fcmpeq, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
775 ; SOFT-DEFAULT: BLX $__nesf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
776 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
777 ; SOFT: ADJCALLSTACKUP
778 ; SOFT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
779 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_ICMP intpred(eq), [[RET]](s32), [[ZERO]]
780 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(ne), [[RET]](s32), [[ZERO]]
781 %3(s32) = G_ZEXT %2(s1)
782 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
783 %r0 = COPY %3(s32)
784 ; CHECK: %r0 = COPY [[REXT]]
785 BX_RET 14, _, implicit %r0
786 ...
787 ---
788 name: test_fcmp_uno_s32
789 # CHECK-LABEL: name: test_fcmp_uno_s32
790 legalized: false
791 # CHECK: legalized: true
792 regBankSelected: false
793 selected: false
794 tracksRegLiveness: true
795 registers:
796 - { id: 0, class: _ }
797 - { id: 1, class: _ }
798 - { id: 2, class: _ }
799 - { id: 3, class: _ }
800 body: |
801 bb.0:
802 liveins: %r0, %r1
803
804 %0(s32) = COPY %r0
805 %1(s32) = COPY %r1
806 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
807 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
808 %2(s1) = G_FCMP floatpred(uno), %0(s32), %1
809 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(uno), [[X]](s32), [[Y]]
810 ; SOFT: ADJCALLSTACKDOWN
811 ; SOFT-DAG: %r0 = COPY [[X]]
812 ; SOFT-DAG: %r1 = COPY [[Y]]
813 ; SOFT-AEABI: BLX $__aeabi_fcmpun, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
814 ; SOFT-DEFAULT: BLX $__unordsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
815 ; SOFT: [[RET:%[0-9]+]](s32) = COPY %r0
816 ; SOFT: ADJCALLSTACKUP
817 ; SOFT-AEABI: [[R:%[0-9]+]](s1) = G_TRUNC [[RET]](s32)
818 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
819 ; SOFT-DEFAULT: [[R:%[0-9]+]](s1) = G_ICMP intpred(ne), [[RET]](s32), [[ZERO]]
820 %3(s32) = G_ZEXT %2(s1)
821 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
822 %r0 = COPY %3(s32)
823 ; CHECK: %r0 = COPY [[REXT]]
824 BX_RET 14, _, implicit %r0
825 ...
826 ---
827 name: test_fcmp_one_s32
828 # CHECK-LABEL: name: test_fcmp_one_s32
829 legalized: false
830 # CHECK: legalized: true
831 regBankSelected: false
832 selected: false
833 tracksRegLiveness: true
834 registers:
835 - { id: 0, class: _ }
836 - { id: 1, class: _ }
837 - { id: 2, class: _ }
838 - { id: 3, class: _ }
839 body: |
840 bb.0:
841 liveins: %r0, %r1
842
843 %0(s32) = COPY %r0
844 %1(s32) = COPY %r1
845 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
846 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
847 %2(s1) = G_FCMP floatpred(one), %0(s32), %1
848 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(one), [[X]](s32), [[Y]]
849 ; SOFT: ADJCALLSTACKDOWN
850 ; SOFT-DAG: %r0 = COPY [[X]]
851 ; SOFT-DAG: %r1 = COPY [[Y]]
852 ; SOFT-AEABI: BLX $__aeabi_fcmpgt, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
853 ; SOFT-DEFAULT: BLX $__gtsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
854 ; SOFT: [[RET1:%[0-9]+]](s32) = COPY %r0
855 ; SOFT: ADJCALLSTACKUP
856 ; SOFT-AEABI: [[R1:%[0-9]+]](s1) = G_TRUNC [[RET1]]
857 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
858 ; SOFT-DEFAULT: [[R1:%[0-9]+]](s1) = G_ICMP intpred(sgt), [[RET1]](s32), [[ZERO]]
859 ; SOFT: ADJCALLSTACKDOWN
860 ; SOFT-DAG: %r0 = COPY [[X]]
861 ; SOFT-DAG: %r1 = COPY [[Y]]
862 ; SOFT-AEABI: BLX $__aeabi_fcmplt, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
863 ; SOFT-DEFAULT: BLX $__ltsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
864 ; SOFT: [[RET2:%[0-9]+]](s32) = COPY %r0
865 ; SOFT: ADJCALLSTACKUP
866 ; SOFT-AEABI: [[R2:%[0-9]+]](s1) = G_TRUNC [[RET2]](s32)
867 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
868 ; SOFT-DEFAULT: [[R2:%[0-9]+]](s1) = G_ICMP intpred(slt), [[RET2]](s32), [[ZERO]]
869 ; SOFT-DAG: [[R1EXT:%[0-9]+]](s32) = G_ANYEXT [[R1]]
870 ; SOFT-DAG: [[R2EXT:%[0-9]+]](s32) = G_ANYEXT [[R2]]
871 ; SOFT: [[REXT:%[0-9]+]](s32) = G_OR [[R1EXT]], [[R2EXT]]
872 ; SOFT: [[R:%[0-9]+]](s1) = G_TRUNC [[REXT]]
873 %3(s32) = G_ZEXT %2(s1)
874 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
875 %r0 = COPY %3(s32)
876 ; CHECK: %r0 = COPY [[REXT]]
877 BX_RET 14, _, implicit %r0
878 ...
879 ---
880 name: test_fcmp_ueq_s32
881 # CHECK-LABEL: name: test_fcmp_ueq_s32
882 legalized: false
883 # CHECK: legalized: true
884 regBankSelected: false
885 selected: false
886 tracksRegLiveness: true
887 registers:
888 - { id: 0, class: _ }
889 - { id: 1, class: _ }
890 - { id: 2, class: _ }
891 - { id: 3, class: _ }
892 body: |
893 bb.0:
894 liveins: %r0, %r1
895
896 %0(s32) = COPY %r0
897 %1(s32) = COPY %r1
898 ; CHECK-DAG: [[X:%[0-9]+]](s32) = COPY %r0
899 ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
900 %2(s1) = G_FCMP floatpred(ueq), %0(s32), %1
901 ; HARD: [[R:%[0-9]+]](s1) = G_FCMP floatpred(ueq), [[X]](s32), [[Y]]
902 ; SOFT: ADJCALLSTACKDOWN
903 ; SOFT-DAG: %r0 = COPY [[X]]
904 ; SOFT-DAG: %r1 = COPY [[Y]]
905 ; SOFT-AEABI: BLX $__aeabi_fcmpeq, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
906 ; SOFT-DEFAULT: BLX $__eqsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
907 ; SOFT: [[RET1:%[0-9]+]](s32) = COPY %r0
908 ; SOFT: ADJCALLSTACKUP
909 ; SOFT-AEABI: [[R1:%[0-9]+]](s1) = G_TRUNC [[RET1]]
910 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
911 ; SOFT-DEFAULT: [[R1:%[0-9]+]](s1) = G_ICMP intpred(eq), [[RET1]](s32), [[ZERO]]
912 ; SOFT: ADJCALLSTACKDOWN
913 ; SOFT-DAG: %r0 = COPY [[X]]
914 ; SOFT-DAG: %r1 = COPY [[Y]]
915 ; SOFT-AEABI: BLX $__aeabi_fcmpun, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
916 ; SOFT-DEFAULT: BLX $__unordsf2, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
917 ; SOFT: [[RET2:%[0-9]+]](s32) = COPY %r0
918 ; SOFT: ADJCALLSTACKUP
919 ; SOFT-AEABI: [[R2:%[0-9]+]](s1) = G_TRUNC [[RET2]](s32)
920 ; SOFT-DEFAULT: [[ZERO:%[0-9]+]](s32) = G_CONSTANT i32 0
921 ; SOFT-DEFAULT: [[R2:%[0-9]+]](s1) = G_ICMP intpred(ne), [[RET2]](s32), [[ZERO]]
922 ; SOFT-DAG: [[R1EXT:%[0-9]+]](s32) = G_ANYEXT [[R1]]
923 ; SOFT-DAG: [[R2EXT:%[0-9]+]](s32) = G_ANYEXT [[R2]]
924 ; SOFT: [[REXT:%[0-9]+]](s32) = G_OR [[R1EXT]], [[R2EXT]]
925 ; SOFT: [[R:%[0-9]+]](s1) = G_TRUNC [[REXT]]
926 %3(s32) = G_ZEXT %2(s1)
927 ; CHECK: [[REXT:%[0-9]+]](s32) = G_ZEXT [[R]](s1)
928 %r0 = COPY %3(s32)
929 ; CHECK: %r0 = COPY [[REXT]]
930 BX_RET 14, _, implicit %r0
931 ...