Skip to content

Commit

Permalink
Merged main:2d89ebd5d17b into amd-gfx:e927f3b64d4d
Browse files Browse the repository at this point in the history
Local branch amd-gfx e927f3b Merged main:d27bb5c375ca into amd-gfx:4b212e426876
Remote branch main 2d89ebd Address unused variable warning
  • Loading branch information
Sw authored and Sw committed Jan 19, 2021
2 parents e927f3b + 2d89ebd commit 0a9c586
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -638,11 +638,11 @@
# endif
# endif

#ifndef __cpp_lib_is_scoped_enum
#error "__cpp_lib_is_scoped_enum should be defined in c++2b"
#endif
#if __cpp_lib_is_scoped_enum != 202011L
#error "__cpp_lib_is_scoped_enum should have the value 202011L in c++2b"
# ifndef __cpp_lib_is_scoped_enum
# error "__cpp_lib_is_scoped_enum should be defined in c++2b"
# endif
# if __cpp_lib_is_scoped_enum != 202011L
# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++2b"
# endif

# ifndef __cpp_lib_is_swappable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3983,11 +3983,11 @@
# endif
# endif

#ifndef __cpp_lib_is_scoped_enum
#error "__cpp_lib_is_scoped_enum should be defined in c++2b"
#endif
#if __cpp_lib_is_scoped_enum != 202011L
#error "__cpp_lib_is_scoped_enum should have the value 202011L in c++2b"
# ifndef __cpp_lib_is_scoped_enum
# error "__cpp_lib_is_scoped_enum should be defined in c++2b"
# endif
# if __cpp_lib_is_scoped_enum != 202011L
# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++2b"
# endif

# ifndef __cpp_lib_is_swappable
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/Analysis/LoopInfoImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,8 @@ static void compareLoops(const LoopT *L, const LoopT *OtherL,
"Mismatched basic blocks in the loops!");

const SmallPtrSetImpl<const BlockT *> &BlocksSet = L->getBlocksSet();
const SmallPtrSetImpl<const BlockT *> &OtherBlocksSet = L->getBlocksSet();
const SmallPtrSetImpl<const BlockT *> &OtherBlocksSet =
OtherL->getBlocksSet();
assert(BlocksSet.size() == OtherBlocksSet.size() &&
llvm::all_of(BlocksSet,
[&OtherBlocksSet](const BlockT *BB) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Config/llvm-config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

/* Indicate that this is LLVM compiled from the amd-gfx branch. */
#define LLVM_HAVE_BRANCH_AMD_GFX
#define LLVM_MAIN_REVISION 377324
#define LLVM_MAIN_REVISION 377330

/* Define if LLVM_ENABLE_DUMP is enabled */
#cmakedefine LLVM_ENABLE_DUMP
Expand Down
30 changes: 24 additions & 6 deletions llvm/lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2127,12 +2127,21 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
Instruction::Xor, Q, MaxRecurse))
return V;

// If the operation is with the result of a select instruction, check whether
// operating on either branch of the select always yields the same value.
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
if (Op0->getType()->isIntOrIntVectorTy(1)) {
// A & (A && B) -> A && B
if (match(Op1, m_Select(m_Specific(Op0), m_Value(), m_Zero())))
return Op1;
else if (match(Op0, m_Select(m_Specific(Op1), m_Value(), m_Zero())))
return Op0;
}
// If the operation is with the result of a select instruction, check
// whether operating on either branch of the select always yields the same
// value.
if (Value *V = ThreadBinOpOverSelect(Instruction::And, Op0, Op1, Q,
MaxRecurse))
return V;
}

// If the operation is with the result of a phi instruction, check whether
// operating on all incoming values of the phi always yields the same value.
Expand Down Expand Up @@ -2303,12 +2312,21 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
Instruction::And, Q, MaxRecurse))
return V;

// If the operation is with the result of a select instruction, check whether
// operating on either branch of the select always yields the same value.
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1)) {
if (Op0->getType()->isIntOrIntVectorTy(1)) {
// A | (A || B) -> A || B
if (match(Op1, m_Select(m_Specific(Op0), m_One(), m_Value())))
return Op1;
else if (match(Op0, m_Select(m_Specific(Op1), m_One(), m_Value())))
return Op0;
}
// If the operation is with the result of a select instruction, check
// whether operating on either branch of the select always yields the same
// value.
if (Value *V = ThreadBinOpOverSelect(Instruction::Or, Op0, Op1, Q,
MaxRecurse))
return V;
}

// (A & C1)|(B & C2)
const APInt *C1, *C2;
Expand Down
29 changes: 20 additions & 9 deletions llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3444,19 +3444,30 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
}
}

// Pull 'not' into operands of select if both operands are one-use compares.
// Pull 'not' into operands of select if both operands are one-use compares
// or one is one-use compare and the other one is a constant.
// Inverting the predicates eliminates the 'not' operation.
// Example:
// not (select ?, (cmp TPred, ?, ?), (cmp FPred, ?, ?) -->
// not (select ?, (cmp TPred, ?, ?), (cmp FPred, ?, ?) -->
// select ?, (cmp InvTPred, ?, ?), (cmp InvFPred, ?, ?)
// TODO: Canonicalize by hoisting 'not' into an arm of the select if only
// 1 select operand is a cmp?
// not (select ?, (cmp TPred, ?, ?), true -->
// select ?, (cmp InvTPred, ?, ?), false
if (auto *Sel = dyn_cast<SelectInst>(Op0)) {
auto *CmpT = dyn_cast<CmpInst>(Sel->getTrueValue());
auto *CmpF = dyn_cast<CmpInst>(Sel->getFalseValue());
if (CmpT && CmpF && CmpT->hasOneUse() && CmpF->hasOneUse()) {
CmpT->setPredicate(CmpT->getInversePredicate());
CmpF->setPredicate(CmpF->getInversePredicate());
Value *TV = Sel->getTrueValue();
Value *FV = Sel->getFalseValue();
auto *CmpT = dyn_cast<CmpInst>(TV);
auto *CmpF = dyn_cast<CmpInst>(FV);
bool InvertibleT = (CmpT && CmpT->hasOneUse()) || isa<Constant>(TV);
bool InvertibleF = (CmpF && CmpF->hasOneUse()) || isa<Constant>(FV);
if (InvertibleT && InvertibleF) {
if (CmpT)
CmpT->setPredicate(CmpT->getInversePredicate());
else
Sel->setTrueValue(ConstantExpr::getNot(cast<Constant>(TV)));
if (CmpF)
CmpF->setPredicate(CmpF->getInversePredicate());
else
Sel->setFalseValue(ConstantExpr::getNot(cast<Constant>(FV)));
return replaceInstUsesWith(I, Sel);
}
}
Expand Down
17 changes: 10 additions & 7 deletions llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ struct ConstantComparesGatherer {
/// vector.
/// One "Extra" case is allowed to differ from the other.
void gather(Value *V) {
bool isEQ = (cast<Instruction>(V)->getOpcode() == Instruction::Or);
bool isEQ = match(V, m_LogicalOr(m_Value(), m_Value()));

// Keep a stack (SmallVector for efficiency) for depth-first traversal
SmallVector<Value *, 8> DFT;
Expand All @@ -707,11 +707,14 @@ struct ConstantComparesGatherer {

if (Instruction *I = dyn_cast<Instruction>(V)) {
// If it is a || (or && depending on isEQ), process the operands.
if (I->getOpcode() == (isEQ ? Instruction::Or : Instruction::And)) {
if (Visited.insert(I->getOperand(1)).second)
DFT.push_back(I->getOperand(1));
if (Visited.insert(I->getOperand(0)).second)
DFT.push_back(I->getOperand(0));
Value *Op0, *Op1;
if (isEQ ? match(I, m_LogicalOr(m_Value(Op0), m_Value(Op1)))
: match(I, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
if (Visited.insert(Op1).second)
DFT.push_back(Op1);
if (Visited.insert(Op0).second)
DFT.push_back(Op0);

continue;
}

Expand Down Expand Up @@ -4147,7 +4150,7 @@ bool SimplifyCFGOpt::SimplifyBranchOnICmpChain(BranchInst *BI,
if (UsedICmps <= 1)
return false;

bool TrueWhenEqual = (Cond->getOpcode() == Instruction::Or);
bool TrueWhenEqual = match(Cond, m_LogicalOr(m_Value(), m_Value()));

// There might be duplicate constants in the list, which the switch
// instruction can't handle, remove them now.
Expand Down
50 changes: 22 additions & 28 deletions llvm/test/Transforms/InstCombine/select-safe-transforms.ll
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ define i1 @cond_eq_or_const(i8 %X, i8 %Y) {
define i1 @merge_and(i1 %X, i1 %Y) {
; CHECK-LABEL: @merge_and(
; CHECK-NEXT: [[C:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false
; CHECK-NEXT: [[RES:%.*]] = and i1 [[C]], [[X]]
; CHECK-NEXT: ret i1 [[RES]]
; CHECK-NEXT: ret i1 [[C]]
;
%c = select i1 %X, i1 %Y, i1 false
%res = and i1 %X, %c
Expand All @@ -67,8 +66,7 @@ define i1 @merge_and(i1 %X, i1 %Y) {
define i1 @merge_or(i1 %X, i1 %Y) {
; CHECK-LABEL: @merge_or(
; CHECK-NEXT: [[C:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
; CHECK-NEXT: [[RES:%.*]] = or i1 [[C]], [[X]]
; CHECK-NEXT: ret i1 [[RES]]
; CHECK-NEXT: ret i1 [[C]]
;
%c = select i1 %X, i1 true, i1 %Y
%res = or i1 %X, %c
Expand All @@ -77,10 +75,10 @@ define i1 @merge_or(i1 %X, i1 %Y) {

define i1 @xor_and(i1 %c, i32 %X, i32 %Y) {
; CHECK-LABEL: @xor_and(
; CHECK-NEXT: [[COMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i1 [[COMP]], i1 false
; CHECK-NEXT: [[RES:%.*]] = xor i1 [[SEL]], true
; CHECK-NEXT: ret i1 [[RES]]
; CHECK-NEXT: [[COMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[COMP]]
; CHECK-NEXT: ret i1 [[SEL]]
;
%comp = icmp ult i32 %X, %Y
%sel = select i1 %c, i1 %comp, i1 false
Expand All @@ -90,10 +88,9 @@ define i1 @xor_and(i1 %c, i32 %X, i32 %Y) {

define <2 x i1> @xor_and2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {
; CHECK-LABEL: @xor_and2(
; CHECK-NEXT: [[COMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> <i1 true, i1 false>
; CHECK-NEXT: [[RES:%.*]] = xor <2 x i1> [[SEL]], <i1 true, i1 true>
; CHECK-NEXT: ret <2 x i1> [[RES]]
; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> <i1 false, i1 true>
; CHECK-NEXT: ret <2 x i1> [[SEL]]
;
%comp = icmp ult <2 x i32> %X, %Y
%sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> <i1 true, i1 false>
Expand All @@ -105,10 +102,9 @@ define <2 x i1> @xor_and2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {

define <2 x i1> @xor_and3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {
; CHECK-LABEL: @xor_and3(
; CHECK-NEXT: [[COMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> <i1 icmp eq (i8* inttoptr (i64 1234 to i8*), i8* @glb), i1 false>
; CHECK-NEXT: [[RES:%.*]] = xor <2 x i1> [[SEL]], <i1 true, i1 true>
; CHECK-NEXT: ret <2 x i1> [[RES]]
; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> <i1 icmp ne (i8* inttoptr (i64 1234 to i8*), i8* @glb), i1 true>
; CHECK-NEXT: ret <2 x i1> [[SEL]]
;
%comp = icmp ult <2 x i32> %X, %Y
%sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> <i1 icmp eq (i8* @glb, i8* inttoptr (i64 1234 to i8*)), i1 false>
Expand All @@ -118,10 +114,10 @@ define <2 x i1> @xor_and3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {

define i1 @xor_or(i1 %c, i32 %X, i32 %Y) {
; CHECK-LABEL: @xor_or(
; CHECK-NEXT: [[COMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[COMP]]
; CHECK-NEXT: [[RES:%.*]] = xor i1 [[SEL]], true
; CHECK-NEXT: ret i1 [[RES]]
; CHECK-NEXT: [[COMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[NOT_C]], i1 [[COMP]], i1 false
; CHECK-NEXT: ret i1 [[SEL]]
;
%comp = icmp ult i32 %X, %Y
%sel = select i1 %c, i1 true, i1 %comp
Expand All @@ -131,10 +127,9 @@ define i1 @xor_or(i1 %c, i32 %X, i32 %Y) {

define <2 x i1> @xor_or2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {
; CHECK-LABEL: @xor_or2(
; CHECK-NEXT: [[COMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 true, i1 false>, <2 x i1> [[COMP]]
; CHECK-NEXT: [[RES:%.*]] = xor <2 x i1> [[SEL]], <i1 true, i1 true>
; CHECK-NEXT: ret <2 x i1> [[RES]]
; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 false, i1 true>, <2 x i1> [[COMP]]
; CHECK-NEXT: ret <2 x i1> [[SEL]]
;
%comp = icmp ult <2 x i32> %X, %Y
%sel = select <2 x i1> %c, <2 x i1> <i1 true, i1 false>, <2 x i1> %comp
Expand All @@ -144,10 +139,9 @@ define <2 x i1> @xor_or2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {

define <2 x i1> @xor_or3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {
; CHECK-LABEL: @xor_or3(
; CHECK-NEXT: [[COMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 icmp eq (i8* inttoptr (i64 1234 to i8*), i8* @glb), i1 false>, <2 x i1> [[COMP]]
; CHECK-NEXT: [[RES:%.*]] = xor <2 x i1> [[SEL]], <i1 true, i1 true>
; CHECK-NEXT: ret <2 x i1> [[RES]]
; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 icmp ne (i8* inttoptr (i64 1234 to i8*), i8* @glb), i1 true>, <2 x i1> [[COMP]]
; CHECK-NEXT: ret <2 x i1> [[SEL]]
;
%comp = icmp ult <2 x i32> %X, %Y
%sel = select <2 x i1> %c, <2 x i1> <i1 icmp eq (i8* @glb, i8* inttoptr (i64 1234 to i8*)), i1 false>, <2 x i1> %comp
Expand Down
Loading

0 comments on commit 0a9c586

Please sign in to comment.