Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
19 changes: 17 additions & 2 deletions llvm/lib/Transforms/Utils/SCCPSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/Analysis/ValueLatticeUtils.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
Expand All @@ -30,6 +31,7 @@
#include <vector>

using namespace llvm;
using namespace PatternMatch;

#define DEBUG_TYPE "sccp"

Expand Down Expand Up @@ -86,7 +88,7 @@ bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
/// Try to use \p Inst's value range from \p Solver to infer the NUW flag.
static bool refineInstruction(SCCPSolver &Solver,
const SmallPtrSetImpl<Value *> &InsertedValues,
Instruction &Inst) {
Instruction &Inst, Statistic &InstRemovedStat) {
bool Changed = false;
auto GetRange = [&Solver, &InsertedValues](Value *Op) {
if (auto *Const = dyn_cast<Constant>(Op))
Expand All @@ -99,6 +101,9 @@ static bool refineInstruction(SCCPSolver &Solver,
Op->getType(), /*UndefAllowed=*/false);
};

Value *X;
const APInt *RHSC;

if (isa<OverflowingBinaryOperator>(Inst)) {
if (Inst.hasNoSignedWrap() && Inst.hasNoUnsignedWrap())
return false;
Expand Down Expand Up @@ -157,6 +162,15 @@ static bool refineInstruction(SCCPSolver &Solver,
GEPNoWrapFlags::noUnsignedWrap());
Changed = true;
}
} else if (match(&Inst, m_And(m_Value(X), m_LowBitMask(RHSC)))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could try generalizing this away from LowBitMask in a followup. For CVP this reduces compile-time, but for IPSCCP it shouldn't matter.

ConstantRange LRange = GetRange(Inst.getOperand(0));
if (!LRange.getUnsignedMax().ule(*RHSC))
return false;

Inst.replaceAllUsesWith(X);
Inst.eraseFromParent();
++InstRemovedStat;
Changed = true;
}

return Changed;
Expand Down Expand Up @@ -249,7 +263,8 @@ bool SCCPSolver::simplifyInstsInBlock(BasicBlock &BB,
} else if (replaceSignedInst(*this, InsertedValues, Inst)) {
MadeChanges = true;
++InstReplacedStat;
} else if (refineInstruction(*this, InsertedValues, Inst)) {
} else if (refineInstruction(*this, InsertedValues, Inst,
InstRemovedStat)) {
MadeChanges = true;
}
}
Expand Down
9 changes: 3 additions & 6 deletions llvm/test/Transforms/SCCP/conditions-ranges-with-undef.ll
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ define void @val_undef_range() {
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: [[A_127:%.*]] = and i32 [[A]], 127
; CHECK-NEXT: call void @use.i32(i32 [[A_127]])
; CHECK-NEXT: call void @use.i32(i32 [[A]])
; CHECK-NEXT: ret void
; CHECK: false:
; CHECK-NEXT: ret void
Expand Down Expand Up @@ -82,8 +81,7 @@ define void @val_singlecrfromundef_range(i1 %cond) {
; CHECK-NEXT: br label [[TRUE:%.*]]
; CHECK: true:
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: [[P_127:%.*]] = and i32 10, 127
; CHECK-NEXT: call void @use.i32(i32 [[P_127]])
; CHECK-NEXT: call void @use.i32(i32 10)
; CHECK-NEXT: ret void
;
entry:
Expand Down Expand Up @@ -131,8 +129,7 @@ define void @val_undef_to_cr_to_overdef_range(i32 %a, i1 %cond) {
; CHECK-NEXT: br i1 [[BC_1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: [[P_127:%.*]] = and i32 [[P]], 127
; CHECK-NEXT: call void @use.i32(i32 [[P_127]])
; CHECK-NEXT: call void @use.i32(i32 [[P]])
; CHECK-NEXT: ret void
; CHECK: false:
; CHECK-NEXT: ret void
Expand Down
5 changes: 2 additions & 3 deletions llvm/test/Transforms/SCCP/range-and.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --verbose
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=sccp %s | FileCheck %s

declare void @use(i1)
Expand Down Expand Up @@ -140,9 +140,8 @@ define i64 @constant_range_and_255_100(i1 %cond, i64 %a) {
; CHECK-NEXT: br label [[BB3]]
; CHECK: bb3:
; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R_1]], [[BB1]] ], [ [[R_2]], [[BB2]] ]
; CHECK-NEXT: [[P_AND:%.*]] = and i64 [[P]], 255
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: ret i64 [[P_AND]]
; CHECK-NEXT: ret i64 [[P]]
;
entry:
br i1 %cond, label %bb1, label %bb2
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/Transforms/SCCP/range-with-undef.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ define i8 @test_binop(i1 %cond, i8 %a) {
; CHECK-NEXT: [[A_EXT:%.*]] = zext i8 [[A]] to i16
; CHECK-NEXT: br label %[[JOIN]]
; CHECK: [[JOIN]]:
; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
; CHECK-NEXT: [[AND:%.*]] = and i16 [[PHI]], -1
; CHECK-NEXT: [[AND:%.*]] = phi i16 [ undef, %[[ENTRY]] ], [ [[A_EXT]], %[[IF]] ]
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[AND]] to i8
; CHECK-NEXT: ret i8 [[TRUNC]]
;
Expand Down
Loading