mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
fcfe9b03ff
As noted by the FIXME comment, this is not correct based on our current FMF semantics. We should be propagating FMF from the final value in a sequence (in this case the 'select'). So the behavior even without this patch is wrong, but we did not allow FMF on 'select' until recently. But if we do the correct thing right now in this patch, we'll inevitably introduce regressions because we have not wired up FMF propagation for 'phi' and 'select' in other passes (like SimplifyCFG) or other places in InstCombine. I'm not seeing a better incremental way to make progress. That said, the potential extra damage over the existing wrong behavior from this patch is very limited. AFAIK, the only way to have different FMF on IR in the same function is if we have LTO inlined IR from 2 modules that were compiled using different fast-math settings. As seen in the tests, we may actually see some improvements with this patch because adding the FMF to the 'select' allows matching to min/max intrinsics that were previously missed (in the common case, the 'fcmp' and 'select' should have identical FMF to begin with). Next steps in the transition: Make similar changes in instcombine as needed. Enable phi-to-select FMF propagation in SimplifyCFG. Remove dependencies on fcmp with FMF. Deprecate FMF on fcmp. Differential Revision: https://reviews.llvm.org/D69720
139 lines
4.9 KiB
LLVM
139 lines
4.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -instcombine < %s | FileCheck %s
|
|
|
|
define float @select_max_ugt(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_max_ugt(
|
|
; CHECK-NEXT: [[CMP_INV:%.*]] = fcmp arcp ole float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select arcp i1 [[CMP_INV]], float [[B]], float [[A]]
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp arcp ugt float %a, %b
|
|
%sel = select arcp i1 %cmp, float %a, float %b
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_max_uge(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_max_uge(
|
|
; CHECK-NEXT: [[CMP_INV:%.*]] = fcmp nnan olt float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select nnan i1 [[CMP_INV]], float [[B]], float [[A]]
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp nnan uge float %a, %b
|
|
%sel = select ninf i1 %cmp, float %a, float %b
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_min_ugt(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_min_ugt(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call fast float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp fast ugt float %a, %b
|
|
%sel = select reassoc i1 %cmp, float %b, float %a
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_min_uge(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_min_uge(
|
|
; CHECK-NEXT: [[CMP_INV:%.*]] = fcmp nsz olt float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select nsz i1 [[CMP_INV]], float [[A]], float [[B]]
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp nsz uge float %a, %b
|
|
%sel = select fast i1 %cmp, float %b, float %a
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_max_ult(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_max_ult(
|
|
; CHECK-NEXT: [[CMP_INV:%.*]] = fcmp arcp oge float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select arcp i1 [[CMP_INV]], float [[A]], float [[B]]
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp arcp ult float %a, %b
|
|
%sel = select ninf nnan i1 %cmp, float %b, float %a
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_max_ule(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_max_ule(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = call fast float @llvm.maxnum.f32(float [[A:%.*]], float [[B:%.*]])
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp fast ule float %a, %b
|
|
%sel = select nsz i1 %cmp, float %b, float %a
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_min_ult(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_min_ult(
|
|
; CHECK-NEXT: [[CMP_INV:%.*]] = fcmp nsz oge float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select nsz i1 [[CMP_INV]], float [[B]], float [[A]]
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp nsz ult float %a, %b
|
|
%sel = select fast i1 %cmp, float %a, float %b
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_min_ule(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_min_ule(
|
|
; CHECK-NEXT: [[CMP_INV:%.*]] = fcmp arcp ogt float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select arcp i1 [[CMP_INV]], float [[B]], float [[A]]
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp arcp ule float %a, %b
|
|
%sel = select ninf i1 %cmp, float %a, float %b
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_fcmp_une(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_fcmp_une(
|
|
; CHECK-NEXT: [[CMP_INV:%.*]] = fcmp reassoc oeq float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select reassoc i1 [[CMP_INV]], float [[B]], float [[A]]
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp reassoc une float %a, %b
|
|
%sel = select nnan i1 %cmp, float %a, float %b
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_fcmp_ueq(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_fcmp_ueq(
|
|
; CHECK-NEXT: [[CMP_INV:%.*]] = fcmp reassoc one float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select reassoc i1 [[CMP_INV]], float [[B]], float [[A]]
|
|
; CHECK-NEXT: ret float [[TMP1]]
|
|
;
|
|
%cmp = fcmp reassoc ueq float %a, %b
|
|
%sel = select arcp nnan i1 %cmp, float %a, float %b
|
|
ret float %sel
|
|
}
|
|
|
|
declare void @foo(i1)
|
|
|
|
define float @select_max_ugt_2_use_cmp(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_max_ugt_2_use_cmp(
|
|
; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ugt float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: call void @foo(i1 [[CMP]])
|
|
; CHECK-NEXT: [[SEL:%.*]] = select fast i1 [[CMP]], float [[A]], float [[B]]
|
|
; CHECK-NEXT: ret float [[SEL]]
|
|
;
|
|
%cmp = fcmp reassoc ugt float %a, %b
|
|
call void @foo(i1 %cmp)
|
|
%sel = select fast i1 %cmp, float %a, float %b
|
|
ret float %sel
|
|
}
|
|
|
|
define float @select_min_uge_2_use_cmp(float %a, float %b) {
|
|
; CHECK-LABEL: define {{[^@]+}}@select_min_uge_2_use_cmp(
|
|
; CHECK-NEXT: [[CMP:%.*]] = fcmp ninf uge float [[A:%.*]], [[B:%.*]]
|
|
; CHECK-NEXT: call void @foo(i1 [[CMP]])
|
|
; CHECK-NEXT: [[SEL:%.*]] = select nsz i1 [[CMP]], float [[B]], float [[A]]
|
|
; CHECK-NEXT: ret float [[SEL]]
|
|
;
|
|
%cmp = fcmp ninf uge float %a, %b
|
|
call void @foo(i1 %cmp)
|
|
%sel = select nsz i1 %cmp, float %b, float %a
|
|
ret float %sel
|
|
}
|