; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
declare void @llvm.assume(i1 noundef)
; Just something to let us check that separate_storage bundles don't break
; anything when given an operand that's not an instruction to fold.
@some_global = global i32 777
define void @simple_folding(ptr %a, ptr %b) {
; CHECK-LABEL: @simple_folding(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[A:%.*]], ptr [[B:%.*]]) ]
; CHECK-NEXT: ret void
;
entry:
%p1 = getelementptr i8, ptr %a, i64 123
%p2 = getelementptr i8, ptr %b, i64 777
call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %p2)]
ret void
}
define i64 @folds_removed_operands(ptr %a, ptr %b, i64 %n1, i64 %n2) {
; CHECK-LABEL: @folds_removed_operands(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i64 [[N2:%.*]], 1
; CHECK-NEXT: [[Y:%.*]] = add i64 [[N1:%.*]], [[REASS_ADD]]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[A:%.*]], ptr [[B:%.*]]) ]
; CHECK-NEXT: ret i64 [[Y]]
;
entry:
; Ordinarily, n1 + n2 + n2 would get canonicalized into n1 + (n2 << 1) unless
; there's another use of n1 + n2. Make sure that we remember to put removed
; arguments to separate_storage bundles back on the worklist.
%x = add i64 %n1, %n2
%y = add i64 %x, %n2
%p1 = getelementptr i8, ptr %a, i64 %x
call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %b)]
ret i64 %y
}
define void @handles_globals(ptr %a) {
; CHECK-LABEL: @handles_globals(
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[A:%.*]], ptr @some_global) ]
; CHECK-NEXT: ret void
;
%derived = getelementptr i8, ptr @some_global, i65 3
call void @llvm.assume(i1 1) ["separate_storage"(ptr %a, ptr %derived)]
ret void
}