Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ cont2:
; CHECK-IR: br i1 {{.*}}, label %trap

; We still have to call it as virtual.
; CHECK-IR: %call3 = tail call i32 %7
; CHECK-IR: %call3 = tail call i32 %8
%call3 = tail call i32 %8(%struct.A* nonnull %obj, i32 %call)
ret i32 %call3
}
Expand Down
7 changes: 3 additions & 4 deletions clang/test/CodeGenOpenCL/convergent.cl
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,10 @@ void test_merge_if(int a) {
// CHECK-DAG: declare spir_func void @f() local_unnamed_addr #2
// CHECK-DAG: declare spir_func void @g() local_unnamed_addr #2


// Test two if's are not merged.
// CHECK-LABEL: define spir_func void @test_no_merge_if(i32 %a) local_unnamed_addr #1
// CHECK: %[[tobool:.+]] = icmp eq i32 %a, 0
// CHECK: br i1 %[[tobool]], label %[[if_end:.+]], label %[[if_then:.+]]
// CHECK: %[[tobool:.+]] = icmp ne i32 %a, 0
// CHECK: br i1 %[[tobool]], label %[[if_then:.+]], label %[[if_end:.+]]
// CHECK: [[if_then]]:
// CHECK: tail call spir_func void @f()
// CHECK-NOT: call spir_func void @convfun()
Expand All @@ -72,7 +71,7 @@ void test_merge_if(int a) {
// CHECK: [[if_end]]:
// CHECK-NOT: phi i1
// CHECK: tail call spir_func void @convfun() #[[attr4:.+]]
// CHECK: br i1 %[[tobool]], label %[[if_end3:.+]], label %[[if_then2:.+]]
// CHECK: br i1 %[[tobool]], label %[[if_then2:.+]], label %[[if_end3:.+]]
// CHECK: [[if_then2]]:
// CHECK: tail call spir_func void @g()
// CHECK: br label %[[if_end3:.+]]
Expand Down
48 changes: 2 additions & 46 deletions llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5304,47 +5304,6 @@ static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I) {
return new ICmpInst(FlippedStrictness->first, Op0, FlippedStrictness->second);
}

/// If we have a comparison with a non-canonical predicate, if we can update
/// all the users, invert the predicate and adjust all the users.
static CmpInst *canonicalizeICmpPredicate(CmpInst &I) {
// Is the predicate already canonical?
CmpInst::Predicate Pred = I.getPredicate();
if (InstCombiner::isCanonicalPredicate(Pred))
return nullptr;

// Can all users be adjusted to predicate inversion?
if (!InstCombiner::canFreelyInvertAllUsersOf(&I, /*IgnoredUser=*/nullptr))
return nullptr;

// Ok, we can canonicalize comparison!
// Let's first invert the comparison's predicate.
I.setPredicate(CmpInst::getInversePredicate(Pred));
I.setName(I.getName() + ".not");

// And now let's adjust every user.
for (User *U : I.users()) {
switch (cast<Instruction>(U)->getOpcode()) {
case Instruction::Select: {
auto *SI = cast<SelectInst>(U);
SI->swapValues();
SI->swapProfMetadata();
break;
}
case Instruction::Br:
cast<BranchInst>(U)->swapSuccessors(); // swaps prof metadata too
break;
case Instruction::Xor:
U->replaceAllUsesWith(&I);
break;
default:
llvm_unreachable("Got unexpected user - out of sync with "
"canFreelyInvertAllUsersOf() ?");
}
}

return &I;
}

/// Integer compare with boolean values can always be turned into bitwise ops.
static Instruction *canonicalizeICmpBool(ICmpInst &I,
InstCombiner::BuilderTy &Builder) {
Expand Down Expand Up @@ -5583,11 +5542,8 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
if (Instruction *Res = canonicalizeICmpBool(I, Builder))
return Res;

if (Instruction *Res = canonicalizeCmpWithConstant(I))
return Res;

if (Instruction *Res = canonicalizeICmpPredicate(I))
return Res;
if (ICmpInst *NewICmp = canonicalizeCmpWithConstant(I))
return NewICmp;

if (Instruction *Res = foldICmpWithConstant(I))
return Res;
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2584,7 +2584,21 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, *this))
return I;

// Canonicalize a one-use integer compare with a non-canonical predicate by
// inverting the predicate and swapping the select operands. This matches a
// compare canonicalization for conditional branches.
// TODO: Should we do the same for FP compares?
CmpInst::Predicate Pred;
if (match(CondVal, m_OneUse(m_ICmp(Pred, m_Value(), m_Value()))) &&
!isCanonicalPredicate(Pred)) {
// Swap true/false values and condition.
CmpInst *Cond = cast<CmpInst>(CondVal);
Cond->setPredicate(CmpInst::getInversePredicate(Pred));
SI.swapValues();
SI.swapProfMetadata();
Worklist.push(Cond);
return &SI;
}

if (SelType->isIntOrIntVectorTy(1) &&
TrueVal->getType() == CondVal->getType()) {
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2843,9 +2843,9 @@ Instruction *InstCombinerImpl::visitBranchInst(BranchInst &BI) {
return replaceOperand(
BI, 0, ConstantInt::getFalse(BI.getCondition()->getType()));

// Canonicalize, for example, fcmp_one -> fcmp_oeq.
// Canonicalize, for example, icmp_ne -> icmp_eq or fcmp_one -> fcmp_oeq.
CmpInst::Predicate Pred;
if (match(&BI, m_Br(m_OneUse(m_FCmp(Pred, m_Value(), m_Value())),
if (match(&BI, m_Br(m_OneUse(m_Cmp(Pred, m_Value(), m_Value())),
m_BasicBlock(), m_BasicBlock())) &&
!isCanonicalPredicate(Pred)) {
// Swap destinations and condition.
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/ThinLTO/X86/cfi-devirt.ll
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ cont2:

; Check that traps are conditional. Invalid TYPE_ID can cause
; unconditional traps.
; CHECK-IR: br i1 {{.*}}, label %trap, label %cont2
; CHECK-IR: br i1 {{.*}}, label %trap

; We still have to call it as virtual.
; CHECK-IR: %call3 = tail call i32 %7
; CHECK-IR: %call3 = tail call i32 %8
%call3 = tail call i32 %8(%struct.A* nonnull %obj, i32 %call)
ret i32 %call3
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ declare void @use1(i1)
define i8 @p0(i8 %x, i8 %v0, i8 %v1) {
; CHECK-LABEL: @p0(
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]], !prof !0
; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V1:%.*]], i8 [[V0:%.*]], !prof !0
; CHECK-NEXT: ret i8 [[R]]
;
%t0 = and i8 %x, 1
Expand All @@ -20,8 +20,8 @@ define i8 @p0(i8 %x, i8 %v0, i8 %v1) {
define i8 @p1(i8 %x, i8 %v0, i8 %v1) {
; CHECK-LABEL: @p1(
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]]
; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V1:%.*]], i8 [[V0:%.*]]
; CHECK-NEXT: ret i8 [[R]]
;
%t0 = and i8 %x, 1
Expand Down Expand Up @@ -51,14 +51,14 @@ define i8 @t3(i8 %x, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8* %out, i1 %c) {
; CHECK-LABEL: @t3(
; CHECK-NEXT: bb0:
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0
; CHECK-NEXT: [[T1:%.*]] = icmp ne i8 [[T0]], 0
; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]]
; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]]
; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1
; CHECK-NEXT: br label [[BB2]]
; CHECK: bb2:
; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1]], i8 [[V2:%.*]], i8 [[V3:%.*]]
; CHECK-NEXT: ret i8 [[R1]]
;
bb0:
Expand All @@ -76,10 +76,10 @@ bb2:
define i8 @t4(i8 %x, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8* %out) {
; CHECK-LABEL: @t4(
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0
; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]]
; CHECK-NEXT: [[T1:%.*]] = icmp ne i8 [[T0]], 0
; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]]
; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1
; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]]
; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1]], i8 [[V2:%.*]], i8 [[V3:%.*]]
; CHECK-NEXT: ret i8 [[R1]]
;
%t0 = and i8 %x, 1
Expand Down Expand Up @@ -112,8 +112,8 @@ define i8 @n6(i8 %x, i8 %v0, i8 %v1) {
define i8 @n7(i8 %x, i8 %v0, i8 %v1) {
; CHECK-LABEL: @n7(
; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[T1_NOT_NOT:%.*]] = icmp eq i8 [[T0]], 0
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT_NOT]], i8 [[V0:%.*]], i8 [[V1:%.*]]
; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0
; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]]
; CHECK-NEXT: ret i8 [[R]]
;
%t0 = and i8 %x, 1
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/InstCombine/icmp-mul-zext.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ define i32 @sterix(i32, i8, i64) {
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[MUL]], [[SH_PROM]]
; CHECK-NEXT: [[CONV2:%.*]] = zext i32 [[SHR]] to i64
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw nsw i64 [[CONV]], [[CONV2]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[MUL3]], 4294967296
; CHECK-NEXT: br i1 [[TMP3]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i64 [[MUL3]], 4294967295
; CHECK-NEXT: br i1 [[TMP3]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]]
; CHECK: lor.rhs:
; CHECK-NEXT: [[AND:%.*]] = and i64 [[MUL3]], [[TMP2]]
; CHECK-NEXT: [[CONV4:%.*]] = trunc i64 [[AND]] to i32
; CHECK-NEXT: [[TOBOOL7_NOT:%.*]] = icmp eq i32 [[CONV4]], 0
; CHECK-NEXT: [[PHITMP:%.*]] = zext i1 [[TOBOOL7_NOT]] to i32
; CHECK-NEXT: [[TOBOOL7:%.*]] = icmp eq i32 [[CONV4]], 0
; CHECK-NEXT: [[PHI_CAST:%.*]] = zext i1 [[TOBOOL7]] to i32
; CHECK-NEXT: br label [[LOR_END]]
; CHECK: lor.end:
; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[PHITMP]], [[LOR_RHS]] ]
; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[PHI_CAST]], [[LOR_RHS]] ]
; CHECK-NEXT: ret i32 [[TMP4]]
;
entry:
Expand Down
28 changes: 14 additions & 14 deletions llvm/test/Transforms/InstCombine/logical-select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) {

define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-LABEL: @bar(
; CHECK-NEXT: [[E_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[E_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]
; CHECK-NEXT: [[E:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[E]], i32 [[C:%.*]], i32 [[D:%.*]]
; CHECK-NEXT: ret i32 [[TMP1]]
;
%e = icmp slt i32 %a, %b
Expand Down Expand Up @@ -69,8 +69,8 @@ define i32 @fold_inverted_icmp_preds(i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-LABEL: @fold_inverted_icmp_preds(
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[C:%.*]], i32 0
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]]
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 0, i32 [[D:%.*]]
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 0, i32 [[D:%.*]]
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]
; CHECK-NEXT: ret i32 [[OR]]
;
Expand All @@ -88,8 +88,8 @@ define i32 @fold_inverted_icmp_preds_reverse(i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-LABEL: @fold_inverted_icmp_preds_reverse(
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 [[C:%.*]]
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]]
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 [[D:%.*]], i32 0
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 [[D:%.*]], i32 0
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]
; CHECK-NEXT: ret i32 [[OR]]
;
Expand Down Expand Up @@ -124,8 +124,8 @@ define i32 @fold_inverted_fcmp_preds(float %a, float %b, i32 %c, i32 %d) {

define <2 x i32> @fold_inverted_icmp_vector_preds(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c, <2 x i32> %d) {
; CHECK-LABEL: @fold_inverted_icmp_vector_preds(
; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq <2 x i32> [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[C:%.*]]
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> [[C:%.*]]
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq <2 x i32> [[A]], [[B]]
; CHECK-NEXT: [[SEL2:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[D:%.*]], <2 x i32> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SEL1]], [[SEL2]]
Expand Down Expand Up @@ -535,9 +535,9 @@ define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c)

define i32 @allSignBits(i32 %cond, i32 %tval, i32 %fval) {
; CHECK-LABEL: @allSignBits(
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp slt i32 [[COND:%.*]], 0
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTNOT]], i32 [[TVAL:%.*]], i32 [[FVAL:%.*]]
; CHECK-NEXT: ret i32 [[TMP1]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[COND:%.*]], -1
; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[FVAL:%.*]], i32 [[TVAL:%.*]]
; CHECK-NEXT: ret i32 [[TMP2]]
;
%bitmask = ashr i32 %cond, 31
%not_bitmask = xor i32 %bitmask, -1
Expand All @@ -549,9 +549,9 @@ define i32 @allSignBits(i32 %cond, i32 %tval, i32 %fval) {

define <4 x i8> @allSignBits_vec(<4 x i8> %cond, <4 x i8> %tval, <4 x i8> %fval) {
; CHECK-LABEL: @allSignBits_vec(
; CHECK-NEXT: [[DOTNOT:%.*]] = icmp sgt <4 x i8> [[COND:%.*]], <i8 -1, i8 -1, i8 -1, i8 -1>
; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[DOTNOT]], <4 x i8> [[FVAL:%.*]], <4 x i8> [[TVAL:%.*]]
; CHECK-NEXT: ret <4 x i8> [[TMP1]]
; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <4 x i8> [[COND:%.*]], <i8 -1, i8 -1, i8 -1, i8 -1>
; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> [[FVAL:%.*]], <4 x i8> [[TVAL:%.*]]
; CHECK-NEXT: ret <4 x i8> [[TMP2]]
;
%bitmask = ashr <4 x i8> %cond, <i8 7, i8 7, i8 7, i8 7>
%not_bitmask = xor <4 x i8> %bitmask, <i8 -1, i8 -1, i8 -1, i8 -1>
Expand Down
Loading