Skip to content

Commit e14a615

Browse files
author
git apple-llvm automerger
committed
Merge commit '783887043241' from apple/master into swift/master-next
2 parents c85f56e + 7838870 commit e14a615

File tree

8 files changed

+88
-0
lines changed

8 files changed

+88
-0
lines changed

llvm/include/llvm/Analysis/InstructionSimplify.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
259259
/// Given a callsite, fold the result or return null.
260260
Value *SimplifyCall(CallBase *Call, const SimplifyQuery &Q);
261261

262+
/// Given an operand for a Freeze, see if we can fold the result.
263+
/// If not, this returns null.
264+
Value *SimplifyFreezeInst(Value *Op, const SimplifyQuery &Q);
265+
262266
/// See if we can compute a simplified version of this instruction. If not,
263267
/// return null.
264268
Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q,

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,10 @@ class Value;
561561
/// the parent of I.
562562
bool programUndefinedIfFullPoison(const Instruction *PoisonI);
563563

564+
/// Return true if this function can prove that V is never undef value
565+
/// or poison value.
566+
bool isGuaranteedNotToBeUndefOrPoison(const Value *V);
567+
564568
/// Specific patterns of select instructions we can match.
565569
enum SelectPatternFlavor {
566570
SPF_UNKNOWN = 0,

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5241,6 +5241,19 @@ Value *llvm::SimplifyCall(CallBase *Call, const SimplifyQuery &Q) {
52415241
return ConstantFoldCall(Call, F, ConstantArgs, Q.TLI);
52425242
}
52435243

5244+
/// Given operands for a Freeze, see if we can fold the result.
5245+
static Value *SimplifyFreezeInst(Value *Op0) {
5246+
// Use a utility function defined in ValueTracking.
5247+
if (llvm::isGuaranteedNotToBeUndefOrPoison(Op0))
5248+
return Op0;
5249+
// We have room for improvement.
5250+
return nullptr;
5251+
}
5252+
5253+
Value *llvm::SimplifyFreezeInst(Value *Op0, const SimplifyQuery &Q) {
5254+
return ::SimplifyFreezeInst(Op0);
5255+
}
5256+
52445257
/// See if we can compute a simplified version of this instruction.
52455258
/// If not, this returns null.
52465259

@@ -5383,6 +5396,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const SimplifyQuery &SQ,
53835396
Result = SimplifyCall(cast<CallInst>(I), Q);
53845397
break;
53855398
}
5399+
case Instruction::Freeze:
5400+
Result = SimplifyFreezeInst(I->getOperand(0), Q);
5401+
break;
53865402
#define HANDLE_CAST_INST(num, opc, clas) case Instruction::opc:
53875403
#include "llvm/IR/Instruction.def"
53885404
#undef HANDLE_CAST_INST

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4221,6 +4221,20 @@ bool llvm::isOverflowIntrinsicNoWrap(const WithOverflowInst *WO,
42214221
return llvm::any_of(GuardingBranches, AllUsesGuardedByBranch);
42224222
}
42234223

4224+
bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V) {
4225+
// If the value is a freeze instruction, then it can never
4226+
// be undef or poison.
4227+
if (isa<FreezeInst>(V))
4228+
return true;
4229+
// TODO: Some instructions are guaranteed to return neither undef
4230+
// nor poison if their arguments are not poison/undef.
4231+
4232+
// TODO: Deal with other Constant subclasses.
4233+
if (isa<ConstantInt>(V) || isa<GlobalVariable>(V))
4234+
return true;
4235+
4236+
return false;
4237+
}
42244238

42254239
OverflowResult llvm::computeOverflowForSignedAdd(const AddOperator *Add,
42264240
const DataLayout &DL,

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner
446446
Instruction *visitLandingPadInst(LandingPadInst &LI);
447447
Instruction *visitVAStartInst(VAStartInst &I);
448448
Instruction *visitVACopyInst(VACopyInst &I);
449+
Instruction *visitFreeze(FreezeInst &I);
449450

450451
/// Specify what to return for unhandled instructions.
451452
Instruction *visitInstruction(Instruction &I) { return nullptr; }

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3131,6 +3131,15 @@ Instruction *InstCombiner::visitLandingPadInst(LandingPadInst &LI) {
31313131
return nullptr;
31323132
}
31333133

3134+
Instruction *InstCombiner::visitFreeze(FreezeInst &I) {
3135+
Value *Op0 = I.getOperand(0);
3136+
3137+
if (Value *V = SimplifyFreezeInst(Op0, SQ.getWithInstruction(&I)))
3138+
return replaceInstUsesWith(I, V);
3139+
3140+
return nullptr;
3141+
}
3142+
31343143
/// Try to move the specified instruction from its current block into the
31353144
/// beginning of DestBlock, which can only happen if it's safe to move the
31363145
/// instruction past all of the instructions between it and the end of its
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -instcombine -S | FileCheck %s
3+
4+
define i32 @fold(i32 %x) {
5+
; CHECK-LABEL: @fold(
6+
; CHECK-NEXT: [[Y:%.*]] = freeze i32 [[X:%.*]]
7+
; CHECK-NEXT: ret i32 [[Y]]
8+
;
9+
%y = freeze i32 %x
10+
%z = freeze i32 %y
11+
ret i32 %z
12+
}
13+
14+
define i32 @make_const() {
15+
; CHECK-LABEL: @make_const(
16+
; CHECK-NEXT: ret i32 10
17+
;
18+
%x = freeze i32 10
19+
ret i32 %x
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -instsimplify -S | FileCheck %s
3+
4+
define i32 @fold(i32 %x) {
5+
; CHECK-LABEL: @fold(
6+
; CHECK-NEXT: [[Y:%.*]] = freeze i32 [[X:%.*]]
7+
; CHECK-NEXT: ret i32 [[Y]]
8+
;
9+
%y = freeze i32 %x
10+
%z = freeze i32 %y
11+
ret i32 %z
12+
}
13+
14+
define i32 @make_const() {
15+
; CHECK-LABEL: @make_const(
16+
; CHECK-NEXT: ret i32 10
17+
;
18+
%x = freeze i32 10
19+
ret i32 %x
20+
}

0 commit comments

Comments
 (0)