Simon Pilgrim d561259a08
[DAG] visitFREEZE - replace multiple frozen/unfrozen uses of an SDValue with just the frozen node (#150017)
Similar to InstCombinerImpl::freezeOtherUses, attempt to ensure that we
merge multiple frozen/unfrozen uses of a SDValue. This fixes a number of
hasOneUse() problems when trying to push FREEZE nodes through the DAG.

Remove SimplifyMultipleUseDemandedBits handling of FREEZE nodes as we
now want to keep the common node, and not bypass for some nodes just
because of DemandedElts.

Fixes #149799
2025-08-05 09:24:09 +01:00

299 lines
7.5 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
; RUN: llc < %s -mtriple=ve-unknown-unknown -enable-no-signed-zeros-fp-math \
; RUN: -enable-no-nans-fp-math | FileCheck %s -check-prefix=OPT
define double @minf64(double, double) {
; CHECK-LABEL: minf64:
; CHECK: # %bb.0:
; CHECK-NEXT: fcmp.d %s2, %s0, %s1
; CHECK-NEXT: cmov.d.lt %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: minf64:
; OPT: # %bb.0:
; OPT-NEXT: fmin.d %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = fcmp olt double %0, %1
%4 = select i1 %3, double %0, double %1
ret double %4
}
define double @min2f64(double, double) {
; CHECK-LABEL: min2f64:
; CHECK: # %bb.0:
; CHECK-NEXT: fcmp.d %s2, %s0, %s1
; CHECK-NEXT: cmov.d.le %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: min2f64:
; OPT: # %bb.0:
; OPT-NEXT: fmin.d %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = fcmp ole double %0, %1
%4 = select i1 %3, double %0, double %1
ret double %4
}
define double @minuf64(double, double) {
; CHECK-LABEL: minuf64:
; CHECK: # %bb.0:
; CHECK-NEXT: fcmp.d %s2, %s0, %s1
; CHECK-NEXT: cmov.d.ltnan %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: minuf64:
; OPT: # %bb.0:
; OPT-NEXT: fmin.d %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = fcmp ult double %0, %1
%4 = select i1 %3, double %0, double %1
ret double %4
}
define double @min2uf64(double, double) {
; CHECK-LABEL: min2uf64:
; CHECK: # %bb.0:
; CHECK-NEXT: fcmp.d %s2, %s0, %s1
; CHECK-NEXT: cmov.d.lenan %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: min2uf64:
; OPT: # %bb.0:
; OPT-NEXT: fmin.d %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = fcmp ule double %0, %1
%4 = select i1 %3, double %0, double %1
ret double %4
}
define float @minf32(float, float) {
; CHECK-LABEL: minf32:
; CHECK: # %bb.0:
; CHECK-NEXT: fcmp.s %s2, %s0, %s1
; CHECK-NEXT: cmov.s.lt %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: minf32:
; OPT: # %bb.0:
; OPT-NEXT: fmin.s %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = fcmp olt float %0, %1
%4 = select i1 %3, float %0, float %1
ret float %4
}
define float @min2f32(float, float) {
; CHECK-LABEL: min2f32:
; CHECK: # %bb.0:
; CHECK-NEXT: fcmp.s %s2, %s0, %s1
; CHECK-NEXT: cmov.s.le %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: min2f32:
; OPT: # %bb.0:
; OPT-NEXT: fmin.s %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = fcmp ole float %0, %1
%4 = select i1 %3, float %0, float %1
ret float %4
}
define float @minuf32(float, float) {
; CHECK-LABEL: minuf32:
; CHECK: # %bb.0:
; CHECK-NEXT: fcmp.s %s2, %s0, %s1
; CHECK-NEXT: cmov.s.ltnan %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: minuf32:
; OPT: # %bb.0:
; OPT-NEXT: fmin.s %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = fcmp ult float %0, %1
%4 = select i1 %3, float %0, float %1
ret float %4
}
define float @min2uf32(float, float) {
; CHECK-LABEL: min2uf32:
; CHECK: # %bb.0:
; CHECK-NEXT: fcmp.s %s2, %s0, %s1
; CHECK-NEXT: cmov.s.lenan %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: min2uf32:
; OPT: # %bb.0:
; OPT-NEXT: fmin.s %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = fcmp ule float %0, %1
%4 = select i1 %3, float %0, float %1
ret float %4
}
define i64 @mini64(i64, i64) {
; CHECK-LABEL: mini64:
; CHECK: # %bb.0:
; CHECK-NEXT: mins.l %s0, %s0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: mini64:
; OPT: # %bb.0:
; OPT-NEXT: mins.l %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = icmp slt i64 %0, %1
%4 = select i1 %3, i64 %0, i64 %1
ret i64 %4
}
define i64 @min2i64(i64, i64) {
; CHECK-LABEL: min2i64:
; CHECK: # %bb.0:
; CHECK-NEXT: mins.l %s0, %s0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: min2i64:
; OPT: # %bb.0:
; OPT-NEXT: mins.l %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = icmp sle i64 %0, %1
%4 = select i1 %3, i64 %0, i64 %1
ret i64 %4
}
define i64 @minu64(i64, i64) {
; CHECK-LABEL: minu64:
; CHECK: # %bb.0:
; CHECK-NEXT: cmpu.l %s2, %s0, %s1
; CHECK-NEXT: cmov.l.lt %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: minu64:
; OPT: # %bb.0:
; OPT-NEXT: cmpu.l %s2, %s0, %s1
; OPT-NEXT: cmov.l.lt %s1, %s0, %s2
; OPT-NEXT: or %s0, 0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = icmp ult i64 %0, %1
%4 = select i1 %3, i64 %0, i64 %1
ret i64 %4
}
define i64 @min2u64(i64, i64) {
; CHECK-LABEL: min2u64:
; CHECK: # %bb.0:
; CHECK-NEXT: cmpu.l %s2, %s0, %s1
; CHECK-NEXT: cmov.l.le %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: min2u64:
; OPT: # %bb.0:
; OPT-NEXT: cmpu.l %s2, %s0, %s1
; OPT-NEXT: cmov.l.le %s1, %s0, %s2
; OPT-NEXT: or %s0, 0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = icmp ule i64 %0, %1
%4 = select i1 %3, i64 %0, i64 %1
ret i64 %4
}
define i32 @mini32(i32, i32) {
; CHECK-LABEL: mini32:
; CHECK: # %bb.0:
; CHECK-NEXT: mins.w.sx %s0, %s0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: mini32:
; OPT: # %bb.0:
; OPT-NEXT: mins.w.sx %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = icmp slt i32 %0, %1
%4 = select i1 %3, i32 %0, i32 %1
ret i32 %4
}
define i32 @min2i32(i32, i32) {
; CHECK-LABEL: min2i32:
; CHECK: # %bb.0:
; CHECK-NEXT: mins.w.sx %s0, %s0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: min2i32:
; OPT: # %bb.0:
; OPT-NEXT: mins.w.sx %s0, %s0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = icmp sle i32 %0, %1
%4 = select i1 %3, i32 %0, i32 %1
ret i32 %4
}
define i32 @minu32(i32, i32) {
; CHECK-LABEL: minu32:
; CHECK: # %bb.0:
; CHECK-NEXT: cmpu.w %s2, %s0, %s1
; CHECK-NEXT: cmov.w.lt %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: minu32:
; OPT: # %bb.0:
; OPT-NEXT: cmpu.w %s2, %s0, %s1
; OPT-NEXT: cmov.w.lt %s1, %s0, %s2
; OPT-NEXT: or %s0, 0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = icmp ult i32 %0, %1
%4 = select i1 %3, i32 %0, i32 %1
ret i32 %4
}
define i32 @min2u32(i32, i32) {
; CHECK-LABEL: min2u32:
; CHECK: # %bb.0:
; CHECK-NEXT: cmpu.w %s2, %s0, %s1
; CHECK-NEXT: cmov.w.le %s1, %s0, %s2
; CHECK-NEXT: or %s0, 0, %s1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: min2u32:
; OPT: # %bb.0:
; OPT-NEXT: cmpu.w %s2, %s0, %s1
; OPT-NEXT: cmov.w.le %s1, %s0, %s2
; OPT-NEXT: or %s0, 0, %s1
; OPT-NEXT: b.l.t (, %s10)
%3 = icmp ule i32 %0, %1
%4 = select i1 %3, i32 %0, i32 %1
ret i32 %4
}
define zeroext i1 @mini1(i1 zeroext, i1 zeroext) {
; CHECK-LABEL: mini1:
; CHECK: # %bb.0:
; CHECK-NEXT: and %s2, 1, %s0
; CHECK-NEXT: and %s0, %s1, %s0
; CHECK-NEXT: cmov.w.ne %s0, %s1, %s2
; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1
; CHECK-NEXT: b.l.t (, %s10)
;
; OPT-LABEL: mini1:
; OPT: # %bb.0:
; OPT-NEXT: and %s2, 1, %s0
; OPT-NEXT: and %s0, %s1, %s0
; OPT-NEXT: cmov.w.ne %s0, %s1, %s2
; OPT-NEXT: adds.w.zx %s0, %s0, (0)1
; OPT-NEXT: b.l.t (, %s10)
%3 = xor i1 %0, true
%4 = and i1 %3, %1
%5 = select i1 %4, i1 %0, i1 %1
ret i1 %5
}