@@ -278,3 +278,210 @@ end:
278278}
279279
280280declare void @foo (i32 )
281+
282+
283+ define i1 @simplify_fcmp_implied_by_dom_cond_range_true (float %x ) {
284+ ; CHECK-LABEL: @simplify_fcmp_implied_by_dom_cond_range_true(
285+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
286+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
287+ ; CHECK: if.then:
288+ ; CHECK-NEXT: ret i1 true
289+ ; CHECK: if.else:
290+ ; CHECK-NEXT: ret i1 false
291+ ;
292+ %cmp = fcmp olt float %x , 0 .0
293+ br i1 %cmp , label %if.then , label %if.else
294+
295+ if.then:
296+ %cmp2 = fcmp olt float %x , 1 .0
297+ ret i1 %cmp2
298+
299+ if.else:
300+ ret i1 false
301+ }
302+
303+ define i1 @simplify_fcmp_in_else_implied_by_dom_cond_range_true (float %x ) {
304+ ; CHECK-LABEL: @simplify_fcmp_in_else_implied_by_dom_cond_range_true(
305+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 1.000000e+00
306+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
307+ ; CHECK: if.then:
308+ ; CHECK-NEXT: ret i1 true
309+ ; CHECK: if.else:
310+ ; CHECK-NEXT: ret i1 true
311+ ;
312+ %cmp = fcmp olt float %x , 1 .0
313+ br i1 %cmp , label %if.then , label %if.else
314+
315+ if.then:
316+ ret i1 true
317+
318+ if.else:
319+ %cmp2 = fcmp uge float %x , 0 .5
320+ ret i1 %cmp2
321+ }
322+
323+ define i1 @simplify_fcmp_implied_by_dom_cond_range_false (float %x ) {
324+ ; CHECK-LABEL: @simplify_fcmp_implied_by_dom_cond_range_false(
325+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
326+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
327+ ; CHECK: if.then:
328+ ; CHECK-NEXT: ret i1 false
329+ ; CHECK: if.else:
330+ ; CHECK-NEXT: ret i1 false
331+ ;
332+ %cmp = fcmp olt float %x , 0 .0
333+ br i1 %cmp , label %if.then , label %if.else
334+
335+ if.then:
336+ %cmp2 = fcmp ogt float %x , 1 .0
337+ ret i1 %cmp2
338+
339+ if.else:
340+ ret i1 false
341+ }
342+
343+ define i1 @simplify_fcmp_implied_by_dom_cond_pred_true (float %x , float %y ) {
344+ ; CHECK-LABEL: @simplify_fcmp_implied_by_dom_cond_pred_true(
345+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
346+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
347+ ; CHECK: if.then:
348+ ; CHECK-NEXT: ret i1 true
349+ ; CHECK: if.else:
350+ ; CHECK-NEXT: ret i1 false
351+ ;
352+ %cmp = fcmp olt float %x , %y
353+ br i1 %cmp , label %if.then , label %if.else
354+
355+ if.then:
356+ %cmp2 = fcmp ole float %x , %y
357+ ret i1 %cmp2
358+
359+ if.else:
360+ ret i1 false
361+ }
362+
363+ define i1 @simplify_fcmp_implied_by_dom_cond_pred_false (float %x , float %y ) {
364+ ; CHECK-LABEL: @simplify_fcmp_implied_by_dom_cond_pred_false(
365+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
366+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
367+ ; CHECK: if.then:
368+ ; CHECK-NEXT: ret i1 false
369+ ; CHECK: if.else:
370+ ; CHECK-NEXT: ret i1 false
371+ ;
372+ %cmp = fcmp olt float %x , %y
373+ br i1 %cmp , label %if.then , label %if.else
374+
375+ if.then:
376+ %cmp2 = fcmp ogt float %x , %y
377+ ret i1 %cmp2
378+
379+ if.else:
380+ ret i1 false
381+ }
382+
383+ define i1 @simplify_fcmp_implied_by_dom_cond_pred_commuted (float %x , float %y ) {
384+ ; CHECK-LABEL: @simplify_fcmp_implied_by_dom_cond_pred_commuted(
385+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
386+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
387+ ; CHECK: if.then:
388+ ; CHECK-NEXT: ret i1 true
389+ ; CHECK: if.else:
390+ ; CHECK-NEXT: ret i1 false
391+ ;
392+ %cmp = fcmp olt float %x , %y
393+ br i1 %cmp , label %if.then , label %if.else
394+
395+ if.then:
396+ %cmp2 = fcmp oge float %y , %x
397+ ret i1 %cmp2
398+
399+ if.else:
400+ ret i1 false
401+ }
402+
403+ ; Negative tests
404+
405+ define i1 @simplify_fcmp_implied_by_dom_cond_wrong_range (float %x ) {
406+ ; CHECK-LABEL: @simplify_fcmp_implied_by_dom_cond_wrong_range(
407+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
408+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
409+ ; CHECK: if.then:
410+ ; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X]], -1.000000e+00
411+ ; CHECK-NEXT: ret i1 [[CMP2]]
412+ ; CHECK: if.else:
413+ ; CHECK-NEXT: ret i1 false
414+ ;
415+ %cmp = fcmp olt float %x , 0 .0
416+ br i1 %cmp , label %if.then , label %if.else
417+
418+ if.then:
419+ %cmp2 = fcmp olt float %x , -1 .0
420+ ret i1 %cmp2
421+
422+ if.else:
423+ ret i1 false
424+ }
425+
426+ define i1 @simplify_fcmp_implied_by_dom_cond_range_mismatched_operand (float %x , float %y ) {
427+ ; CHECK-LABEL: @simplify_fcmp_implied_by_dom_cond_range_mismatched_operand(
428+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
429+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
430+ ; CHECK: if.then:
431+ ; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[Y:%.*]], 1.000000e+00
432+ ; CHECK-NEXT: ret i1 [[CMP2]]
433+ ; CHECK: if.else:
434+ ; CHECK-NEXT: ret i1 false
435+ ;
436+ %cmp = fcmp olt float %x , 0 .0
437+ br i1 %cmp , label %if.then , label %if.else
438+
439+ if.then:
440+ %cmp2 = fcmp olt float %y , 1 .0
441+ ret i1 %cmp2
442+
443+ if.else:
444+ ret i1 false
445+ }
446+
447+ define i1 @simplify_fcmp_implied_by_dom_cond_wrong_pred (float %x , float %y ) {
448+ ; CHECK-LABEL: @simplify_fcmp_implied_by_dom_cond_wrong_pred(
449+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp ole float [[X:%.*]], [[Y:%.*]]
450+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
451+ ; CHECK: if.then:
452+ ; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X]], [[Y]]
453+ ; CHECK-NEXT: ret i1 [[CMP2]]
454+ ; CHECK: if.else:
455+ ; CHECK-NEXT: ret i1 false
456+ ;
457+ %cmp = fcmp ole float %x , %y
458+ br i1 %cmp , label %if.then , label %if.else
459+
460+ if.then:
461+ %cmp2 = fcmp olt float %x , %y
462+ ret i1 %cmp2
463+
464+ if.else:
465+ ret i1 false
466+ }
467+
468+ define i1 @simplify_fcmp_implied_by_dom_cond_pred_mismatched_operand (float %x , float %y , float %z ) {
469+ ; CHECK-LABEL: @simplify_fcmp_implied_by_dom_cond_pred_mismatched_operand(
470+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
471+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
472+ ; CHECK: if.then:
473+ ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ole float [[X]], [[Z:%.*]]
474+ ; CHECK-NEXT: ret i1 [[CMP2]]
475+ ; CHECK: if.else:
476+ ; CHECK-NEXT: ret i1 false
477+ ;
478+ %cmp = fcmp olt float %x , %y
479+ br i1 %cmp , label %if.then , label %if.else
480+
481+ if.then:
482+ %cmp2 = fcmp ole float %x , %z
483+ ret i1 %cmp2
484+
485+ if.else:
486+ ret i1 false
487+ }
0 commit comments