Skip to content

Commit 9eb1df1

Browse files
committed
[InstCombine] Fold integer stores using llvm.assume
1 parent 61ba00e commit 9eb1df1

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,16 @@ Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) {
15351535
if (Value *V = simplifyNonNullOperand(Ptr, /*HasDereferenceable=*/true))
15361536
return replaceOperand(SI, 1, V);
15371537

1538+
// If the stored value is constant at this point (e.g., constrained by a
1539+
// guaranteed-to-execute llvm.assume), fold the store.
1540+
if (Val->getType()->isIntegerTy() && !isa<Constant>(Val) &&
1541+
!isa<PoisonValue>(Val)) {
1542+
KnownBits Known = computeKnownBits(Val, &SI);
1543+
if (Known.isConstant())
1544+
return replaceOperand(
1545+
SI, 0, ConstantInt::get(SI.getContext(), Known.getConstant()));
1546+
}
1547+
15381548
return nullptr;
15391549
}
15401550

llvm/test/Transforms/InstCombine/store-assume-fold.ll

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ declare void @llvm.assume(i1)
1111
define void @assume_store_i1(i1 %x) {
1212
; CHECK-LABEL: define void @assume_store_i1(
1313
; CHECK-SAME: i1 [[X:%.*]]) {
14-
; CHECK-NEXT: store i1 [[X]], ptr @a, align 1
14+
; CHECK-NEXT: store i1 true, ptr @a, align 1
1515
; CHECK-NEXT: call void @llvm.assume(i1 [[X]])
1616
; CHECK-NEXT: ret void
1717
;
@@ -23,7 +23,7 @@ define void @assume_store_i1(i1 %x) {
2323
define void @assume_store_i1_not(i1 %x) {
2424
; CHECK-LABEL: define void @assume_store_i1_not(
2525
; CHECK-SAME: i1 [[X:%.*]]) {
26-
; CHECK-NEXT: store i1 [[X]], ptr @a, align 1
26+
; CHECK-NEXT: store i1 false, ptr @a, align 1
2727
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[X]], true
2828
; CHECK-NEXT: call void @llvm.assume(i1 [[NOT]])
2929
; CHECK-NEXT: ret void
@@ -39,7 +39,7 @@ define i1 @assume_store_i1_xor(ptr %G) {
3939
; CHECK-SAME: ptr [[G:%.*]]) {
4040
; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[G]], align 1
4141
; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[L]], true
42-
; CHECK-NEXT: store i1 [[XOR]], ptr @a, align 1
42+
; CHECK-NEXT: store i1 true, ptr @a, align 1
4343
; CHECK-NEXT: call void @llvm.assume(i1 [[XOR]])
4444
; CHECK-NEXT: ret i1 [[XOR]]
4545
;
@@ -53,7 +53,7 @@ define i1 @assume_store_i1_xor(ptr %G) {
5353
define void @assume_store_i32_eq(i32 %x) {
5454
; CHECK-LABEL: define void @assume_store_i32_eq(
5555
; CHECK-SAME: i32 [[X:%.*]]) {
56-
; CHECK-NEXT: store i32 [[X]], ptr @b, align 4
56+
; CHECK-NEXT: store i32 10, ptr @b, align 4
5757
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 10
5858
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
5959
; CHECK-NEXT: ret void
@@ -68,9 +68,8 @@ define void @unreachable_implies_false(i8 %x) {
6868
; CHECK-LABEL: define void @unreachable_implies_false(
6969
; CHECK-SAME: i8 [[X:%.*]]) {
7070
; CHECK-NEXT: [[RET:.*:]]
71-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X]], 5
72-
; CHECK-NEXT: store i1 [[CMP]], ptr @a, align 1
73-
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[CMP]], true
71+
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i8 [[X]], 6
72+
; CHECK-NEXT: store i1 false, ptr @a, align 1
7473
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
7574
; CHECK-NEXT: ret void
7675
;

0 commit comments

Comments
 (0)