Skip to content

Commit ae2e781

Browse files
committed
[InstCombine] Do not use operands info in replaceInInstruction
1 parent 712e07c commit ae2e781

File tree

4 files changed

+46
-22
lines changed

4 files changed

+46
-22
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -822,15 +822,24 @@ bool isSafeToSpeculativelyExecute(const Instruction *I,
822822
const Instruction *CtxI = nullptr,
823823
AssumptionCache *AC = nullptr,
824824
const DominatorTree *DT = nullptr,
825-
const TargetLibraryInfo *TLI = nullptr);
826-
827-
inline bool
828-
isSafeToSpeculativelyExecute(const Instruction *I, BasicBlock::iterator CtxI,
829-
AssumptionCache *AC = nullptr,
830-
const DominatorTree *DT = nullptr,
831-
const TargetLibraryInfo *TLI = nullptr) {
825+
const TargetLibraryInfo *TLI = nullptr,
826+
bool UseInstrInfo = true);
827+
828+
inline bool isSafeToSpeculativelyExecute(const Instruction *I,
829+
BasicBlock::iterator CtxI,
830+
AssumptionCache *AC = nullptr,
831+
const DominatorTree *DT = nullptr,
832+
const TargetLibraryInfo *TLI = nullptr,
833+
bool UseInstrInfo = true) {
832834
// Take an iterator, and unwrap it into an Instruction *.
833-
return isSafeToSpeculativelyExecute(I, &*CtxI, AC, DT, TLI);
835+
return isSafeToSpeculativelyExecute(I, &*CtxI, AC, DT, TLI, UseInstrInfo);
836+
}
837+
838+
/// Don't use information from its operands. This helper is used when its
839+
/// operands are going to be replaced.
840+
inline bool isSafeToSpeculativelyExecuteWithoutInstrInfo(const Instruction *I) {
841+
return isSafeToSpeculativelyExecute(I, nullptr, nullptr, nullptr, nullptr,
842+
/*UseInstrInfo=*/false);
834843
}
835844

836845
/// This returns the same result as isSafeToSpeculativelyExecute if Opcode is
@@ -853,7 +862,7 @@ isSafeToSpeculativelyExecute(const Instruction *I, BasicBlock::iterator CtxI,
853862
bool isSafeToSpeculativelyExecuteWithOpcode(
854863
unsigned Opcode, const Instruction *Inst, const Instruction *CtxI = nullptr,
855864
AssumptionCache *AC = nullptr, const DominatorTree *DT = nullptr,
856-
const TargetLibraryInfo *TLI = nullptr);
865+
const TargetLibraryInfo *TLI = nullptr, bool UseInstrInfo = true);
857866

858867
/// Returns true if the result or effects of the given instructions \p I
859868
/// depend values not reachable through the def use graph.

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6756,19 +6756,17 @@ bool llvm::mustSuppressSpeculation(const LoadInst &LI) {
67566756
F.hasFnAttribute(Attribute::SanitizeHWAddress);
67576757
}
67586758

6759-
bool llvm::isSafeToSpeculativelyExecute(const Instruction *Inst,
6760-
const Instruction *CtxI,
6761-
AssumptionCache *AC,
6762-
const DominatorTree *DT,
6763-
const TargetLibraryInfo *TLI) {
6759+
bool llvm::isSafeToSpeculativelyExecute(
6760+
const Instruction *Inst, const Instruction *CtxI, AssumptionCache *AC,
6761+
const DominatorTree *DT, const TargetLibraryInfo *TLI, bool UseInstrInfo) {
67646762
return isSafeToSpeculativelyExecuteWithOpcode(Inst->getOpcode(), Inst, CtxI,
6765-
AC, DT, TLI);
6763+
AC, DT, TLI, UseInstrInfo);
67666764
}
67676765

67686766
bool llvm::isSafeToSpeculativelyExecuteWithOpcode(
67696767
unsigned Opcode, const Instruction *Inst, const Instruction *CtxI,
6770-
AssumptionCache *AC, const DominatorTree *DT,
6771-
const TargetLibraryInfo *TLI) {
6768+
AssumptionCache *AC, const DominatorTree *DT, const TargetLibraryInfo *TLI,
6769+
bool UseInstrInfo) {
67726770
#ifndef NDEBUG
67736771
if (Inst->getOpcode() != Opcode) {
67746772
// Check that the operands are actually compatible with the Opcode override.
@@ -6796,12 +6794,15 @@ bool llvm::isSafeToSpeculativelyExecuteWithOpcode(
67966794
case Instruction::URem: {
67976795
// x / y is undefined if y == 0.
67986796
const APInt *V;
6799-
if (match(Inst->getOperand(1), m_APInt(V)))
6797+
if (UseInstrInfo && match(Inst->getOperand(1), m_APInt(V)))
68006798
return *V != 0;
68016799
return false;
68026800
}
68036801
case Instruction::SDiv:
68046802
case Instruction::SRem: {
6803+
if (!UseInstrInfo)
6804+
return false;
6805+
68056806
// x / y is undefined if y == 0 or x == INT_MIN and y == -1
68066807
const APInt *Numerator, *Denominator;
68076808
if (!match(Inst->getOperand(1), m_APInt(Denominator)))
@@ -6820,6 +6821,9 @@ bool llvm::isSafeToSpeculativelyExecuteWithOpcode(
68206821
return false;
68216822
}
68226823
case Instruction::Load: {
6824+
if (!UseInstrInfo)
6825+
return false;
6826+
68236827
const LoadInst *LI = dyn_cast<LoadInst>(Inst);
68246828
if (!LI)
68256829
return false;

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1248,9 +1248,18 @@ bool InstCombinerImpl::replaceInInstruction(Value *V, Value *Old, Value *New,
12481248
return false;
12491249

12501250
auto *I = dyn_cast<Instruction>(V);
1251-
if (!I || !I->hasOneUse() || !isSafeToSpeculativelyExecute(I))
1251+
if (!I || !I->hasOneUse() || !isSafeToSpeculativelyExecuteWithoutInstrInfo(I))
12521252
return false;
12531253

1254+
// Special handling for replacing called operand
1255+
if (auto *Call = dyn_cast<CallInst>(I)) {
1256+
if (Call->getCalledOperand() == Old) {
1257+
auto *Callee = dyn_cast<Function>(New);
1258+
if (!Callee || !Callee->isSpeculatable())
1259+
return false;
1260+
}
1261+
}
1262+
12541263
bool Changed = false;
12551264
for (Use &U : I->operands()) {
12561265
if (U == Old) {

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
2+
; RUN: opt < %s -passes='instcombine<no-verify-fixpoint>' -S | FileCheck %s
33

44
; PR1822
55

@@ -4720,8 +4720,10 @@ define i8 @select_knownbits_simplify_missing_noundef(i8 %x) {
47204720
define i32 @pr99436() {
47214721
; CHECK-LABEL: @pr99436(
47224722
; CHECK-NEXT: entry:
4723-
; CHECK-NEXT: store i1 true, ptr poison, align 1
4724-
; CHECK-NEXT: ret i32 poison
4723+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr getelementptr (i8, ptr @arr, i64 4), null
4724+
; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr getelementptr (i8, ptr @arr, i64 4), align 4
4725+
; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 0
4726+
; CHECK-NEXT: ret i32 [[RET]]
47254727
;
47264728
entry:
47274729
%alloc = alloca ptr, align 8

0 commit comments

Comments
 (0)