PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
//===---- llvm/unittest/IR/PatternMatch.cpp - PatternMatch unit tests ----===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/Analysis/ValueTracking.h"
|
|
|
|
#include "llvm/IR/BasicBlock.h"
|
|
|
|
#include "llvm/IR/Constants.h"
|
|
|
|
#include "llvm/IR/DataLayout.h"
|
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
2014-01-05 02:07:20 +00:00
|
|
|
#include "llvm/IR/Function.h"
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
#include "llvm/IR/IRBuilder.h"
|
2014-01-05 02:07:20 +00:00
|
|
|
#include "llvm/IR/Instructions.h"
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
#include "llvm/IR/LLVMContext.h"
|
|
|
|
#include "llvm/IR/MDBuilder.h"
|
2014-01-05 02:07:20 +00:00
|
|
|
#include "llvm/IR/Module.h"
|
2014-03-04 12:05:47 +00:00
|
|
|
#include "llvm/IR/NoFolder.h"
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
#include "llvm/IR/Operator.h"
|
2014-03-04 11:08:18 +00:00
|
|
|
#include "llvm/IR/PatternMatch.h"
|
2014-01-05 02:07:20 +00:00
|
|
|
#include "llvm/IR/Type.h"
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
2014-01-05 02:07:20 +00:00
|
|
|
using namespace llvm;
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
using namespace llvm::PatternMatch;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2014-01-05 02:07:20 +00:00
|
|
|
struct PatternMatchTest : ::testing::Test {
|
|
|
|
LLVMContext Ctx;
|
2014-03-06 05:51:42 +00:00
|
|
|
std::unique_ptr<Module> M;
|
2014-01-05 02:07:20 +00:00
|
|
|
Function *F;
|
|
|
|
BasicBlock *BB;
|
2014-01-05 02:23:11 +00:00
|
|
|
IRBuilder<true, NoFolder> IRB;
|
2014-01-05 02:07:20 +00:00
|
|
|
|
|
|
|
PatternMatchTest()
|
|
|
|
: M(new Module("PatternMatchTestModule", Ctx)),
|
|
|
|
F(Function::Create(
|
|
|
|
FunctionType::get(Type::getVoidTy(Ctx), /* IsVarArg */ false),
|
|
|
|
Function::ExternalLinkage, "f", M.get())),
|
2014-01-05 02:23:11 +00:00
|
|
|
BB(BasicBlock::Create(Ctx, "entry", F)), IRB(BB) {}
|
2014-01-05 02:07:20 +00:00
|
|
|
};
|
|
|
|
|
2014-01-05 09:14:53 +00:00
|
|
|
TEST_F(PatternMatchTest, OneUse) {
|
|
|
|
// Build up a little tree of values:
|
|
|
|
//
|
|
|
|
// One = (1 + 2) + 42
|
|
|
|
// Two = One + 42
|
|
|
|
// Leaf = (Two + 8) + (Two + 13)
|
|
|
|
Value *One = IRB.CreateAdd(IRB.CreateAdd(IRB.getInt32(1), IRB.getInt32(2)),
|
|
|
|
IRB.getInt32(42));
|
|
|
|
Value *Two = IRB.CreateAdd(One, IRB.getInt32(42));
|
|
|
|
Value *Leaf = IRB.CreateAdd(IRB.CreateAdd(Two, IRB.getInt32(8)),
|
|
|
|
IRB.CreateAdd(Two, IRB.getInt32(13)));
|
|
|
|
Value *V;
|
|
|
|
|
|
|
|
EXPECT_TRUE(m_OneUse(m_Value(V)).match(One));
|
|
|
|
EXPECT_EQ(One, V);
|
|
|
|
|
|
|
|
EXPECT_FALSE(m_OneUse(m_Value()).match(Two));
|
|
|
|
EXPECT_FALSE(m_OneUse(m_Value()).match(Leaf));
|
|
|
|
}
|
|
|
|
|
2014-01-05 02:07:20 +00:00
|
|
|
TEST_F(PatternMatchTest, FloatingPointOrderedMin) {
|
2014-01-05 02:23:11 +00:00
|
|
|
Type *FltTy = IRB.getFloatTy();
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
Value *L = ConstantFP::get(FltTy, 1.0);
|
|
|
|
Value *R = ConstantFP::get(FltTy, 2.0);
|
2014-01-05 02:07:20 +00:00
|
|
|
Value *MatchL, *MatchR;
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test OLT.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test OLE.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test no match on OGE.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test no match on OGT.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test match on OGE with inverted select.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), R, L)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test match on OGT with inverted select.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), R, L)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
}
|
|
|
|
|
2014-01-05 02:07:20 +00:00
|
|
|
TEST_F(PatternMatchTest, FloatingPointOrderedMax) {
|
2014-01-05 02:23:11 +00:00
|
|
|
Type *FltTy = IRB.getFloatTy();
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
Value *L = ConstantFP::get(FltTy, 1.0);
|
|
|
|
Value *R = ConstantFP::get(FltTy, 2.0);
|
2014-01-05 02:07:20 +00:00
|
|
|
Value *MatchL, *MatchR;
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test OGT.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOGT(L, R), L, R)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test OGE.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOGE(L, R), L, R)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test no match on OLE.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), L, R)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test no match on OLT.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), L, R)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test match on OLE with inverted select.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOLE(L, R), R, L)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
|
|
|
|
2014-01-05 02:07:20 +00:00
|
|
|
// Test match on OLT with inverted select.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpOLT(L, R), R, L)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
|
|
|
}
|
|
|
|
|
2014-01-05 02:07:20 +00:00
|
|
|
TEST_F(PatternMatchTest, FloatingPointUnorderedMin) {
|
2014-01-05 02:23:11 +00:00
|
|
|
Type *FltTy = IRB.getFloatTy();
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
Value *L = ConstantFP::get(FltTy, 1.0);
|
|
|
|
Value *R = ConstantFP::get(FltTy, 2.0);
|
2014-01-05 02:07:20 +00:00
|
|
|
Value *MatchL, *MatchR;
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test ULT.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test ULE.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test no match on UGE.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test no match on UGT.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test match on UGE with inverted select.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), R, L)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test match on UGT with inverted select.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), R, L)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
}
|
|
|
|
|
2014-01-05 02:07:20 +00:00
|
|
|
TEST_F(PatternMatchTest, FloatingPointUnorderedMax) {
|
2014-01-05 02:23:11 +00:00
|
|
|
Type *FltTy = IRB.getFloatTy();
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
Value *L = ConstantFP::get(FltTy, 1.0);
|
|
|
|
Value *R = ConstantFP::get(FltTy, 2.0);
|
2014-01-05 02:07:20 +00:00
|
|
|
Value *MatchL, *MatchR;
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test UGT.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpUGT(L, R), L, R)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test UGE.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpUGE(L, R), L, R)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test no match on ULE.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), L, R)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test no match on ULT.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), L, R)));
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test match on ULE with inverted select.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpULE(L, R), R, L)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
|
|
|
|
// Test match on ULT with inverted select.
|
2014-01-05 02:23:11 +00:00
|
|
|
EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR))
|
|
|
|
.match(IRB.CreateSelect(IRB.CreateFCmpULT(L, R), R, L)));
|
2014-01-05 02:07:20 +00:00
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
}
|
|
|
|
|
2014-01-05 03:28:29 +00:00
|
|
|
TEST_F(PatternMatchTest, OverflowingBinOps) {
|
|
|
|
Value *L = IRB.getInt32(1);
|
|
|
|
Value *R = IRB.getInt32(2);
|
|
|
|
Value *MatchL, *MatchR;
|
|
|
|
|
|
|
|
EXPECT_TRUE(
|
|
|
|
m_NSWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWAdd(L, R)));
|
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
2014-06-08 22:29:17 +00:00
|
|
|
MatchL = MatchR = nullptr;
|
2014-01-05 03:28:29 +00:00
|
|
|
EXPECT_TRUE(
|
|
|
|
m_NSWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWSub(L, R)));
|
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
2014-06-08 22:29:17 +00:00
|
|
|
MatchL = MatchR = nullptr;
|
2014-01-05 03:28:29 +00:00
|
|
|
EXPECT_TRUE(
|
|
|
|
m_NSWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNSWMul(L, R)));
|
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
2014-06-08 22:29:17 +00:00
|
|
|
MatchL = MatchR = nullptr;
|
2014-01-05 03:28:29 +00:00
|
|
|
EXPECT_TRUE(m_NSWShl(m_Value(MatchL), m_Value(MatchR)).match(
|
|
|
|
IRB.CreateShl(L, R, "", /* NUW */ false, /* NSW */ true)));
|
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
|
|
|
|
|
|
|
EXPECT_TRUE(
|
|
|
|
m_NUWAdd(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWAdd(L, R)));
|
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
2014-06-08 22:29:17 +00:00
|
|
|
MatchL = MatchR = nullptr;
|
2014-01-05 03:28:29 +00:00
|
|
|
EXPECT_TRUE(
|
|
|
|
m_NUWSub(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWSub(L, R)));
|
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
2014-06-08 22:29:17 +00:00
|
|
|
MatchL = MatchR = nullptr;
|
2014-01-05 03:28:29 +00:00
|
|
|
EXPECT_TRUE(
|
|
|
|
m_NUWMul(m_Value(MatchL), m_Value(MatchR)).match(IRB.CreateNUWMul(L, R)));
|
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
2014-06-08 22:29:17 +00:00
|
|
|
MatchL = MatchR = nullptr;
|
2014-01-05 03:28:29 +00:00
|
|
|
EXPECT_TRUE(m_NUWShl(m_Value(MatchL), m_Value(MatchR)).match(
|
|
|
|
IRB.CreateShl(L, R, "", /* NUW */ true, /* NSW */ false)));
|
|
|
|
EXPECT_EQ(L, MatchL);
|
|
|
|
EXPECT_EQ(R, MatchR);
|
|
|
|
|
|
|
|
EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWAdd(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWSub(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNUWMul(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWMul(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R)));
|
|
|
|
EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(
|
|
|
|
IRB.CreateShl(L, R, "", /* NUW */ true, /* NSW */ false)));
|
|
|
|
EXPECT_FALSE(m_NSWShl(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
|
|
|
|
|
|
|
|
EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateAdd(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNSWAdd(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWAdd(m_Value(), m_Value()).match(IRB.CreateNUWSub(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateSub(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNSWSub(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWSub(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateMul(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNSWMul(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWMul(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateShl(L, R)));
|
|
|
|
EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(
|
|
|
|
IRB.CreateShl(L, R, "", /* NUW */ false, /* NSW */ true)));
|
|
|
|
EXPECT_FALSE(m_NUWShl(m_Value(), m_Value()).match(IRB.CreateNUWAdd(L, R)));
|
|
|
|
}
|
|
|
|
|
PatternMatch: Matcher for (un)ordered floating point min/max
Add support for matching 'ordered' and 'unordered' floating point min/max
constructs.
In LLVM we can express min/max functions as a combination of compare and select.
We have support for matching such constructs for integers but not for floating
point. In floating point math there is no total order because of the presence of
'NaN'. Therefore, we have to be careful to preserve the original fcmp semantics
when interpreting floating point compare select combinations as a minimum or
maximum function. The resulting 'ordered/unordered' floating point maximum
function has to select the same value as the select/fcmp combination it is based
on.
ordered_max(x,y) = max(x,y) iff x and y are not NaN, y otherwise
unordered_max(x,y) = max(x,y) iff x and y are not NaN, x otherwise
ordered_min(x,y) = min(x,y) iff x and y are not NaN, y otherwise
unordered_min(x,y) = min(x,y) iff x and y are not NaN, x otherwise
This matches the behavior of the underlying select(fcmp(olt/ult/.., L, R), L, R)
construct.
Any code using this predicate has to preserve this semantics.
A follow-up patch will use this to implement floating point min/max reductions
in the vectorizer.
radar://13723044
llvm-svn: 181143
2013-05-05 01:54:46 +00:00
|
|
|
} // anonymous namespace.
|