-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[X86][ABIVerifier] Verify floating point ABI correctness on 64-bit target #111690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…rget A small step to ABIVerifier proposal disscussed in llvm#100757 (comment) Fixes: llvm#111406
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-backend-x86 Author: Phoebe Wang (phoebewang) ChangesA small step to ABIVerifier proposal disscussed in #100757 (comment) Fixes: #111406 Patch is 84.55 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/111690.diff 6 Files Affected:
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 1cd5eb36c4ab69..eff0fde17e84b6 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -619,6 +619,8 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
void verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
const Value *V, bool IsIntrinsic, bool IsInlineAsm);
void verifyFunctionMetadata(ArrayRef<std::pair<unsigned, MDNode *>> MDs);
+ void verifyX86ABI(FunctionType *FT, AttributeList Attrs, const Value *V,
+ unsigned MaxParameterWidth);
void visitConstantExprsRecursively(const Constant *EntryC);
void visitConstantExpr(const ConstantExpr *CE);
@@ -2086,6 +2088,27 @@ void Verifier::checkUnsignedBaseTenFuncAttr(AttributeList Attrs, StringRef Attr,
}
}
+void Verifier::verifyX86ABI(FunctionType *FT, AttributeList Attrs,
+ const Value *V, unsigned MaxParameterWidth) {
+ if (!Attrs.hasFnAttr("target-features"))
+ return;
+
+ StringRef TF = Attrs.getFnAttr("target-features").getValueAsString();
+ // Check SSE feature.
+ Check(!TT.isArch64Bit() || !TF.contains("-sse,") ||
+ !FT->getReturnType()->isFloatTy(),
+ "SSE register return with SSE disabled", V);
+ // Check SSE2 feature.
+ Check(!TT.isArch64Bit() || !TF.contains("-sse2") ||
+ (!FT->getReturnType()->isDoubleTy() &&
+ !FT->getReturnType()->is16bitFPTy()),
+ "SSE2 register return with SSE2 disabled", V);
+ // Check EVEX512 feature.
+ if (MaxParameterWidth >= 512)
+ Check(!TF.contains("+avx512f") || !TF.contains("-evex512"),
+ "512-bit vector arguments require 'evex512' for AVX512", V);
+}
+
// Check parameter attributes against a function type.
// The value V is printed in error messages.
void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
@@ -2335,13 +2358,8 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V);
}
- // Check EVEX512 feature.
- if (MaxParameterWidth >= 512 && Attrs.hasFnAttr("target-features") &&
- TT.isX86()) {
- StringRef TF = Attrs.getFnAttr("target-features").getValueAsString();
- Check(!TF.contains("+avx512f") || !TF.contains("-evex512"),
- "512-bit vector arguments require 'evex512' for AVX512", V);
- }
+ if (TT.isX86())
+ verifyX86ABI(FT, Attrs, V, MaxParameterWidth);
checkUnsignedBaseTenFuncAttr(Attrs, "patchable-function-prefix", V);
checkUnsignedBaseTenFuncAttr(Attrs, "patchable-function-entry", V);
diff --git a/llvm/test/Analysis/CostModel/X86/arith-fp-codesize.ll b/llvm/test/Analysis/CostModel/X86/arith-fp-codesize.ll
index b965a726262e68..65dabc6eb68d81 100644
--- a/llvm/test/Analysis/CostModel/X86/arith-fp-codesize.ll
+++ b/llvm/test/Analysis/CostModel/X86/arith-fp-codesize.ll
@@ -1,5 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
-; RUN: opt < %s -enable-no-nans-fp-math -passes="print<cost-model>" 2>&1 -disable-output -cost-kind=code-size -mtriple=x86_64-- -mattr=-sse2 | FileCheck %s --check-prefixes=CHECK,SSE1
; RUN: opt < %s -enable-no-nans-fp-math -passes="print<cost-model>" 2>&1 -disable-output -cost-kind=code-size -mtriple=x86_64-- -mattr=+sse2 | FileCheck %s --check-prefixes=CHECK,SSE2
; RUN: opt < %s -enable-no-nans-fp-math -passes="print<cost-model>" 2>&1 -disable-output -cost-kind=code-size -mtriple=x86_64-- -mattr=+sse4.2 | FileCheck %s --check-prefixes=CHECK,SSE2
; RUN: opt < %s -enable-no-nans-fp-math -passes="print<cost-model>" 2>&1 -disable-output -cost-kind=code-size -mtriple=x86_64-- -mattr=+avx | FileCheck %s --check-prefixes=CHECK,AVX
@@ -12,17 +11,6 @@
; RUN: opt < %s -enable-no-nans-fp-math -passes="print<cost-model>" 2>&1 -disable-output -cost-kind=code-size -mtriple=x86_64-- -mcpu=btver2 | FileCheck %s --check-prefixes=CHECK,AVX
define i32 @fadd(i32 %arg) {
-; SSE1-LABEL: 'fadd'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fadd float undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fadd <4 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V8F32 = fadd <8 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V16F32 = fadd <16 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = fadd double undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = fadd <2 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = fadd <4 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = fadd <8 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fadd'
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fadd float undef, undef
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fadd <4 x float> undef, undef
@@ -70,17 +58,6 @@ define i32 @fadd(i32 %arg) {
}
define i32 @fsub(i32 %arg) {
-; SSE1-LABEL: 'fsub'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fsub float undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fsub <4 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V8F32 = fsub <8 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V16F32 = fsub <16 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = fsub double undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = fsub <2 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = fsub <4 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = fsub <8 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fsub'
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fsub float undef, undef
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fsub <4 x float> undef, undef
@@ -128,17 +105,6 @@ define i32 @fsub(i32 %arg) {
}
define i32 @fneg_idiom(i32 %arg) {
-; SSE1-LABEL: 'fneg_idiom'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fsub float -0.000000e+00, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V8F32 = fsub <8 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V16F32 = fsub <16 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = fsub double -0.000000e+00, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = fsub <4 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = fsub <8 x double> <double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00, double -0.000000e+00>, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fneg_idiom'
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fsub float -0.000000e+00, undef
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, undef
@@ -186,17 +152,6 @@ define i32 @fneg_idiom(i32 %arg) {
}
define i32 @fneg(i32 %arg) {
-; SSE1-LABEL: 'fneg'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fneg float undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fneg <4 x float> undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V8F32 = fneg <8 x float> undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V16F32 = fneg <16 x float> undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = fneg double undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = fneg <2 x double> undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = fneg <4 x double> undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = fneg <8 x double> undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fneg'
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fneg float undef
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fneg <4 x float> undef
@@ -244,17 +199,6 @@ define i32 @fneg(i32 %arg) {
}
define i32 @fmul(i32 %arg) {
-; SSE1-LABEL: 'fmul'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fmul float undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fmul <4 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V8F32 = fmul <8 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V16F32 = fmul <16 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = fmul double undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = fmul <2 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = fmul <4 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = fmul <8 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fmul'
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fmul float undef, undef
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fmul <4 x float> undef, undef
@@ -302,17 +246,6 @@ define i32 @fmul(i32 %arg) {
}
define i32 @fdiv(i32 %arg) {
-; SSE1-LABEL: 'fdiv'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fdiv float undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fdiv <4 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V8F32 = fdiv <8 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V16F32 = fdiv <16 x float> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = fdiv double undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = fdiv <2 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = fdiv <4 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = fdiv <8 x double> undef, undef
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fdiv'
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = fdiv float undef, undef
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = fdiv <4 x float> undef, undef
@@ -385,17 +318,6 @@ define i32 @frem(i32 %arg) {
}
define i32 @fsqrt(i32 %arg) {
-; SSE1-LABEL: 'fsqrt'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = call float @llvm.sqrt.f32(float undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = call <4 x float> @llvm.sqrt.v4f32(<4 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V8F32 = call <8 x float> @llvm.sqrt.v8f32(<8 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V16F32 = call <16 x float> @llvm.sqrt.v16f32(<16 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = call double @llvm.sqrt.f64(double undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = call <2 x double> @llvm.sqrt.v2f64(<2 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = call <4 x double> @llvm.sqrt.v4f64(<4 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = call <8 x double> @llvm.sqrt.v8f64(<8 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fsqrt'
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = call float @llvm.sqrt.f32(float undef)
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %V4F32 = call <4 x float> @llvm.sqrt.v4f32(<4 x float> undef)
@@ -443,17 +365,6 @@ define i32 @fsqrt(i32 %arg) {
}
define i32 @fabs(i32 %arg) {
-; SSE1-LABEL: 'fabs'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %F32 = call float @llvm.fabs.f32(float undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V4F32 = call <4 x float> @llvm.fabs.v4f32(<4 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V8F32 = call <8 x float> @llvm.fabs.v8f32(<8 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V16F32 = call <16 x float> @llvm.fabs.v16f32(<16 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = call double @llvm.fabs.f64(double undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V2F64 = call <2 x double> @llvm.fabs.v2f64(<2 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V4F64 = call <4 x double> @llvm.fabs.v4f64(<4 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 16 for instruction: %V8F64 = call <8 x double> @llvm.fabs.v8f64(<8 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fabs'
; SSE2-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %F32 = call float @llvm.fabs.f32(float undef)
; SSE2-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V4F32 = call <4 x float> @llvm.fabs.v4f32(<4 x float> undef)
@@ -501,17 +412,6 @@ define i32 @fabs(i32 %arg) {
}
define i32 @fcopysign(i32 %arg) {
-; SSE1-LABEL: 'fcopysign'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %F32 = call float @llvm.copysign.f32(float undef, float undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V4F32 = call <4 x float> @llvm.copysign.v4f32(<4 x float> undef, <4 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V8F32 = call <8 x float> @llvm.copysign.v8f32(<8 x float> undef, <8 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V16F32 = call <16 x float> @llvm.copysign.v16f32(<16 x float> undef, <16 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = call double @llvm.copysign.f64(double undef, double undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = call <2 x double> @llvm.copysign.v2f64(<2 x double> undef, <2 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = call <4 x double> @llvm.copysign.v4f64(<4 x double> undef, <4 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = call <8 x double> @llvm.copysign.v8f64(<8 x double> undef, <8 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fcopysign'
; SSE2-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %F32 = call float @llvm.copysign.f32(float undef, float undef)
; SSE2-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V4F32 = call <4 x float> @llvm.copysign.v4f32(<4 x float> undef, <4 x float> undef)
@@ -559,17 +459,6 @@ define i32 @fcopysign(i32 %arg) {
}
define i32 @fma(i32 %arg) {
-; SSE1-LABEL: 'fma'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = call float @llvm.fma.f32(float undef, float undef, float undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 7 for instruction: %V4F32 = call <4 x float> @llvm.fma.v4f32(<4 x float> undef, <4 x float> undef, <4 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 14 for instruction: %V8F32 = call <8 x float> @llvm.fma.v8f32(<8 x float> undef, <8 x float> undef, <8 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 28 for instruction: %V16F32 = call <16 x float> @llvm.fma.v16f32(<16 x float> undef, <16 x float> undef, <16 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = call double @llvm.fma.f64(double undef, double undef, double undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = call <2 x double> @llvm.fma.v2f64(<2 x double> undef, <2 x double> undef, <2 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = call <4 x double> @llvm.fma.v4f64(<4 x double> undef, <4 x double> undef, <4 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = call <8 x double> @llvm.fma.v8f64(<8 x double> undef, <8 x double> undef, <8 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
-;
; SSE2-LABEL: 'fma'
; SSE2-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = call float @llvm.fma.f32(float undef, float undef, float undef)
; SSE2-NEXT: Cost Model: Found an estimated cost of 7 for instruction: %V4F32 = call <4 x float> @llvm.fma.v4f32(<4 x float> undef, <4 x float> undef, <4 x float> undef)
@@ -617,17 +506,6 @@ define i32 @fma(i32 %arg) {
}
define i32 @rint(i32 %arg) {
-; SSE1-LABEL: 'rint'
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F32 = call float @llvm.rint.f32(float undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 7 for instruction: %V4F32 = call <4 x float> @llvm.rint.v4f32(<4 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 14 for instruction: %V8F32 = call <8 x float> @llvm.rint.v8f32(<8 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 28 for instruction: %V16F32 = call <16 x float> @llvm.rint.v16f32(<16 x float> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %F64 = call double @llvm.rint.f64(double undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = call <2 x double> @llvm.rint.v2f64(<2 x double> undef)
-; SSE1-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = call <4 x double> ...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
llvm/lib/IR/Verifier.cpp
Outdated
// Check SSE2 feature. | ||
Check(!TT.isArch64Bit() || !TF.contains("-sse2") || | ||
(!FT->getReturnType()->isDoubleTy() && | ||
!FT->getReturnType()->is16bitFPTy()), | ||
"SSE2 register return with SSE2 disabled", V); | ||
// Check EVEX512 feature. | ||
if (MaxParameterWidth >= 512) | ||
Check(!TF.contains("+avx512f") || !TF.contains("-evex512"), | ||
"512-bit vector arguments require 'evex512' for AVX512", V); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think anything like this belongs in the IR verifier. It should not be invalid IR. You can always codegen it to something (whether or not some platform ABI defined how to do this is entirely irrelevant)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#111406 is a good illustration to this question. Arbitrarily generating something is unexpected here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is clang backendification. No type should require any specific target properties.
This isn't really a valid way to check for subtarget features either. You have to parse out the whole string and evaluate the final result. e.g. you can do -feature,+feature and +feature wins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is clang backendification. No type should require any specific target properties.
Some type does require specific target properties, e.g., FP16/BF16, which we have limited them in Clang front end.
This isn't really a valid way to check for subtarget features either. You have to parse out the whole string and evaluate the final result. e.g. you can do -feature,+feature and +feature wins
Good catch, done.
@@ -1,5 +1,4 @@ | |||
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py | |||
; RUN: opt < %s -enable-no-nans-fp-math -passes="print<cost-model>" 2>&1 -disable-output -cost-kind=code-size -mtriple=x86_64-- -mattr=-sse2 | FileCheck %s --check-prefixes=CHECK,SSE1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of dropping the test coverage - can you alter the triple to a suitable i686 target?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has no place in the IR verifier. There could be a dedicated ABI linting pass, but this should not be considered invalid IR.
This also needs to use the backend parsing for target-features, which accounts for target-cpu as well as target-features. Clang spams redundant target-features entries with target-cpu, but this is not required
A small step to ABIVerifier proposal disscussed in #100757 (comment)
Fixes: #111406