[llvm] r298939 - [IR] Add AllowContract to FastMathFlags
Adam Nemet via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 28 13:11:52 PDT 2017
Author: anemet
Date: Tue Mar 28 15:11:52 2017
New Revision: 298939
URL: http://llvm.org/viewvc/llvm-project?rev=298939&view=rev
Log:
[IR] Add AllowContract to FastMathFlags
-ffp-contract=fast does not currently work with LTO because it's passed as a
TargetOption to the backend rather than in the IR. This adds it to
FastMathFlags.
This is toward fixing PR25721
Differential Revision: https://reviews.llvm.org/D31164
Modified:
llvm/trunk/docs/LangRef.rst
llvm/trunk/include/llvm/IR/Instruction.h
llvm/trunk/include/llvm/IR/Operator.h
llvm/trunk/lib/AsmParser/LLLexer.cpp
llvm/trunk/lib/AsmParser/LLParser.h
llvm/trunk/lib/AsmParser/LLToken.h
llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/trunk/lib/IR/AsmWriter.cpp
llvm/trunk/lib/IR/Instruction.cpp
llvm/trunk/test/Assembler/fast-math-flags.ll
llvm/trunk/test/Bitcode/compatibility.ll
llvm/trunk/unittests/IR/IRBuilderTest.cpp
Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Tue Mar 28 15:11:52 2017
@@ -2194,6 +2194,10 @@ otherwise unsafe floating point transfor
Allow Reciprocal - Allow optimizations to use the reciprocal of an
argument rather than perform division.
+``contract``
+ Allow floating-point contraction (e.g. fusing a multiply followed by an
+ addition into a fused multiply-and-add).
+
``fast``
Fast - Allow algebraically equivalent transformations that may
dramatically change results in floating point (e.g. reassociate). This
Modified: llvm/trunk/include/llvm/IR/Instruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.h?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instruction.h (original)
+++ llvm/trunk/include/llvm/IR/Instruction.h Tue Mar 28 15:11:52 2017
@@ -345,6 +345,9 @@ public:
/// Determine whether the allow-reciprocal flag is set.
bool hasAllowReciprocal() const;
+ /// Determine whether the allow-contract flag is set.
+ bool hasAllowContract() const;
+
/// Convenience function for getting all the fast-math flags, which must be an
/// operator which supports these flags. See LangRef.html for the meaning of
/// these flags.
Modified: llvm/trunk/include/llvm/IR/Operator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Operator.h?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Operator.h (original)
+++ llvm/trunk/include/llvm/IR/Operator.h Tue Mar 28 15:11:52 2017
@@ -172,12 +172,15 @@ private:
FastMathFlags(unsigned F) : Flags(F) { }
public:
+ /// This is how the bits are used in Value::SubclassOptionalData so they
+ /// should fit there too.
enum {
UnsafeAlgebra = (1 << 0),
NoNaNs = (1 << 1),
NoInfs = (1 << 2),
NoSignedZeros = (1 << 3),
- AllowReciprocal = (1 << 4)
+ AllowReciprocal = (1 << 4),
+ AllowContract = (1 << 5)
};
FastMathFlags() = default;
@@ -193,6 +196,7 @@ public:
bool noInfs() const { return 0 != (Flags & NoInfs); }
bool noSignedZeros() const { return 0 != (Flags & NoSignedZeros); }
bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
+ bool allowContract() const { return 0 != (Flags & AllowContract); }
bool unsafeAlgebra() const { return 0 != (Flags & UnsafeAlgebra); }
/// Flag setters
@@ -200,12 +204,16 @@ public:
void setNoInfs() { Flags |= NoInfs; }
void setNoSignedZeros() { Flags |= NoSignedZeros; }
void setAllowReciprocal() { Flags |= AllowReciprocal; }
+ void setAllowContract(bool B) {
+ Flags = (Flags & ~AllowContract) | B * AllowContract;
+ }
void setUnsafeAlgebra() {
Flags |= UnsafeAlgebra;
setNoNaNs();
setNoInfs();
setNoSignedZeros();
setAllowReciprocal();
+ setAllowContract(true);
}
void operator&=(const FastMathFlags &OtherFlags) {
@@ -257,6 +265,12 @@ private:
(B * FastMathFlags::AllowReciprocal);
}
+ void setHasAllowContract(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~FastMathFlags::AllowContract) |
+ (B * FastMathFlags::AllowContract);
+ }
+
/// Convenience function for setting multiple fast-math flags.
/// FMF is a mask of the bits to set.
void setFastMathFlags(FastMathFlags FMF) {
@@ -300,6 +314,12 @@ public:
return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
}
+ /// Test whether this operation is permitted to
+ /// be floating-point contracted.
+ bool hasAllowContract() const {
+ return (SubclassOptionalData & FastMathFlags::AllowContract) != 0;
+ }
+
/// Convenience function for getting all the fast-math flags
FastMathFlags getFastMathFlags() const {
return FastMathFlags(SubclassOptionalData);
Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Tue Mar 28 15:11:52 2017
@@ -548,6 +548,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(ninf);
KEYWORD(nsz);
KEYWORD(arcp);
+ KEYWORD(contract);
KEYWORD(fast);
KEYWORD(nuw);
KEYWORD(nsw);
Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Tue Mar 28 15:11:52 2017
@@ -193,6 +193,10 @@ namespace llvm {
case lltok::kw_ninf: FMF.setNoInfs(); Lex.Lex(); continue;
case lltok::kw_nsz: FMF.setNoSignedZeros(); Lex.Lex(); continue;
case lltok::kw_arcp: FMF.setAllowReciprocal(); Lex.Lex(); continue;
+ case lltok::kw_contract:
+ FMF.setAllowContract(true);
+ Lex.Lex();
+ continue;
default: return FMF;
}
return FMF;
Modified: llvm/trunk/lib/AsmParser/LLToken.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLToken.h (original)
+++ llvm/trunk/lib/AsmParser/LLToken.h Tue Mar 28 15:11:52 2017
@@ -98,6 +98,7 @@ enum Kind {
kw_ninf,
kw_nsz,
kw_arcp,
+ kw_contract,
kw_fast,
kw_nuw,
kw_nsw,
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Mar 28 15:11:52 2017
@@ -971,6 +971,8 @@ static FastMathFlags getDecodedFastMathF
FMF.setNoSignedZeros();
if (0 != (Val & FastMathFlags::AllowReciprocal))
FMF.setAllowReciprocal();
+ if (0 != (Val & FastMathFlags::AllowContract))
+ FMF.setAllowContract(true);
return FMF;
}
Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Mar 28 15:11:52 2017
@@ -1336,6 +1336,8 @@ static uint64_t getOptimizationFlags(con
Flags |= FastMathFlags::NoSignedZeros;
if (FPMO->hasAllowReciprocal())
Flags |= FastMathFlags::AllowReciprocal;
+ if (FPMO->hasAllowContract())
+ Flags |= FastMathFlags::AllowContract;
}
return Flags;
Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Tue Mar 28 15:11:52 2017
@@ -1073,6 +1073,8 @@ static void WriteOptimizationInfo(raw_os
Out << " nsz";
if (FPO->hasAllowReciprocal())
Out << " arcp";
+ if (FPO->hasAllowContract())
+ Out << " contract";
}
}
Modified: llvm/trunk/lib/IR/Instruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instruction.cpp?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instruction.cpp (original)
+++ llvm/trunk/lib/IR/Instruction.cpp Tue Mar 28 15:11:52 2017
@@ -204,6 +204,11 @@ bool Instruction::hasAllowReciprocal() c
return cast<FPMathOperator>(this)->hasAllowReciprocal();
}
+bool Instruction::hasAllowContract() const {
+ assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op");
+ return cast<FPMathOperator>(this)->hasAllowContract();
+}
+
FastMathFlags Instruction::getFastMathFlags() const {
assert(isa<FPMathOperator>(this) && "getting fast-math flag on invalid op");
return cast<FPMathOperator>(this)->getFastMathFlags();
Modified: llvm/trunk/test/Assembler/fast-math-flags.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/fast-math-flags.ll?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/fast-math-flags.ll (original)
+++ llvm/trunk/test/Assembler/fast-math-flags.ll Tue Mar 28 15:11:52 2017
@@ -74,6 +74,18 @@ entry:
ret float %e
}
+; CHECK: @contract(
+define float @contract(float %x, float %y) {
+entry:
+; CHECK: %a = fsub contract float %x, %y
+ %a = fsub contract float %x, %y
+; CHECK: %b = fadd contract float %x, %y
+ %b = fadd contract float %x, %y
+; CHECK: %c = fmul contract float %a, %b
+ %c = fmul contract float %a, %b
+ ret float %c
+}
+
; CHECK: no_nan_inf
define float @no_nan_inf(float %x, float %y) {
entry:
Modified: llvm/trunk/test/Bitcode/compatibility.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/compatibility.ll?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/test/Bitcode/compatibility.ll (original)
+++ llvm/trunk/test/Bitcode/compatibility.ll Tue Mar 28 15:11:52 2017
@@ -760,6 +760,8 @@ define void @fastmathflags(float %op1, f
; CHECK: %f.nsz = fadd nsz float %op1, %op2
%f.arcp = fadd arcp float %op1, %op2
; CHECK: %f.arcp = fadd arcp float %op1, %op2
+ %f.contract = fadd contract float %op1, %op2
+ ; CHECK: %f.contract = fadd contract float %op1, %op2
%f.fast = fadd fast float %op1, %op2
; CHECK: %f.fast = fadd fast float %op1, %op2
ret void
Modified: llvm/trunk/unittests/IR/IRBuilderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/IRBuilderTest.cpp?rev=298939&r1=298938&r2=298939&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/IRBuilderTest.cpp (original)
+++ llvm/trunk/unittests/IR/IRBuilderTest.cpp Tue Mar 28 15:11:52 2017
@@ -207,7 +207,26 @@ TEST_F(IRBuilderTest, FastMathFlags) {
EXPECT_TRUE(FCmp->hasAllowReciprocal());
Builder.clearFastMathFlags();
-
+
+ // Test FP-contract
+ FC = Builder.CreateFAdd(F, F);
+ ASSERT_TRUE(isa<Instruction>(FC));
+ FAdd = cast<Instruction>(FC);
+ EXPECT_FALSE(FAdd->hasAllowContract());
+
+ FMF.clear();
+ FMF.setAllowContract(true);
+ Builder.setFastMathFlags(FMF);
+
+ FC = Builder.CreateFAdd(F, F);
+ EXPECT_TRUE(Builder.getFastMathFlags().any());
+ EXPECT_TRUE(Builder.getFastMathFlags().AllowContract);
+ ASSERT_TRUE(isa<Instruction>(FC));
+ FAdd = cast<Instruction>(FC);
+ EXPECT_TRUE(FAdd->hasAllowContract());
+
+ Builder.clearFastMathFlags();
+
// Test a call with FMF.
auto CalleeTy = FunctionType::get(Type::getFloatTy(Ctx),
/*isVarArg=*/false);
More information about the llvm-commits
mailing list