[clang] [llvm] Clang/buildFMulAdd: Use negated attribute (PR #121038)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 24 01:02:41 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: YunQiang Su (wzssyqa)
<details>
<summary>Changes</summary>
Use negated attribute if negMul or negAdd. So that we can lower
fneg+fmuladd to fmul+fsub if needed.
1) It can save one machine instruction:
fneg/fmul/fadd vs fmul/fsub
2) In strict mode, `c-a*b` may be different with `c+(-a)*b`.
---
Full diff: https://github.com/llvm/llvm-project/pull/121038.diff
7 Files Affected:
- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+4)
- (modified) clang/test/CodeGen/constrained-math-builtins.c (+3-3)
- (modified) llvm/docs/LangRef.rst (+6)
- (modified) llvm/include/llvm/Bitcode/LLVMBitCodes.h (+1)
- (modified) llvm/include/llvm/IR/Attributes.td (+3)
- (modified) llvm/lib/Bitcode/Writer/BitcodeWriter.cpp (+2)
- (modified) llvm/lib/Transforms/Utils/CodeExtractor.cpp (+1)
``````````diff
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 4b71bd730ce12c..14d73de055d8ec 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4120,6 +4120,10 @@ static Value* buildFMulAdd(llvm::Instruction *MulOp, Value *Addend,
CGF.CGM.getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
Addend->getType()),
{MulOp0, MulOp1, Addend});
+ if (negMul)
+ dyn_cast<llvm::CallBase>(FMulAdd)->addParamAttr(0, llvm::Attribute::Negated);
+ if (negAdd)
+ dyn_cast<llvm::CallBase>(FMulAdd)->addParamAttr(2, llvm::Attribute::Negated);
} else {
FMulAdd = Builder.CreateCall(
CGF.CGM.getIntrinsic(llvm::Intrinsic::fmuladd, Addend->getType()),
diff --git a/clang/test/CodeGen/constrained-math-builtins.c b/clang/test/CodeGen/constrained-math-builtins.c
index 68b9e75283c547..f044f15e98918b 100644
--- a/clang/test/CodeGen/constrained-math-builtins.c
+++ b/clang/test/CodeGen/constrained-math-builtins.c
@@ -392,12 +392,12 @@ void bar(float f) {
// CHECK: call float @llvm.experimental.constrained.fmuladd.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
// CHECK: fneg
- // CHECK: call double @llvm.experimental.constrained.fmuladd.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
+ // CHECK: call double @llvm.experimental.constrained.fmuladd.f64(double %{{.*}}, double %{{.*}}, double negated %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
// CHECK: fneg
// CHECK: call x86_fp80 @llvm.experimental.constrained.fmuladd.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
// CHECK: fneg
// CHECK: fneg
- // CHECK: call float @llvm.experimental.constrained.fmuladd.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
+ // CHECK: call float @llvm.experimental.constrained.fmuladd.f32(float negated %{{.*}}, float %{{.*}}, float negated %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
// CHECK: fneg
- // CHECK: call float @llvm.experimental.constrained.fmuladd.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
+ // CHECK: call float @llvm.experimental.constrained.fmuladd.f32(float negated %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
};
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 7e01331b20c570..bf37e6a788c4b6 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1573,6 +1573,12 @@ Currently, only the following parameter attributes are defined:
| pinf | Positive infinity | 512 |
+-------+----------------------+---------------+
+``negated``
+ The function parameter marked with this attribute is negated from
+ its opposite number by the frontend like Clang. The middle end or
+ backend should convert it back if possible. For example if -(a*b)
+ is converted to (-a)*b, the arg0 of `fmul` instruction should be
+ marked with `negated` attribute.
``alignstack(<n>)``
This indicates the alignment that should be considered by the backend when
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 21fd27d9838db7..7e9d174db22026 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -788,6 +788,7 @@ enum AttributeKindCodes {
ATTR_KIND_NO_EXT = 99,
ATTR_KIND_NO_DIVERGENCE_SOURCE = 100,
ATTR_KIND_SANITIZE_TYPE = 101,
+ ATTR_KIND_NEGATED = 102,
};
enum ComdatSelectionKindCodes {
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index 61955cf883c3f1..baeca5d53f3c46 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -162,6 +162,9 @@ def Memory : IntAttr<"memory", IntersectCustom, [FnAttr]>;
/// Forbidden floating-point classes.
def NoFPClass : IntAttr<"nofpclass", IntersectCustom, [ParamAttr, RetAttr]>;
+/// Converted from the opposite number
+def Negated : EnumAttr<"negated", IntersectAnd, [ParamAttr, RetAttr]>;
+
/// Function must be optimized for size first.
def MinSize : EnumAttr<"minsize", IntersectPreserve, [FnAttr]>;
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index b4efd3928a2e6f..e87c9d2e13883d 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -755,6 +755,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_MEMORY;
case Attribute::NoFPClass:
return bitc::ATTR_KIND_NOFPCLASS;
+ case Attribute::Negated:
+ return bitc::ATTR_KIND_NEGATED;
case Attribute::Naked:
return bitc::ATTR_KIND_NAKED;
case Attribute::Nest:
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index 7ddb9e22c83441..4e1a8c560078aa 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -918,6 +918,7 @@ Function *CodeExtractor::constructFunctionDeclaration(
case Attribute::PresplitCoroutine:
case Attribute::Memory:
case Attribute::NoFPClass:
+ case Attribute::Negated:
case Attribute::CoroDestroyOnlyWhenComplete:
case Attribute::CoroElideSafe:
case Attribute::NoDivergenceSource:
``````````
</details>
https://github.com/llvm/llvm-project/pull/121038
More information about the llvm-commits
mailing list