; 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 [[REASS_ADD]], [[N1:%.*]] ; 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 }