xref: /llvm-project/llvm/test/Transforms/SeparateConstOffsetFromGEP/split-gep-or-as-add.ll (revision d4a0154902fb9b0611ed857134b26a64a1d5ad1e)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -S -passes="separate-const-offset-from-gep<lower-gep>" < %s | FileCheck %s
3
4;; Check that or operations, either with operands with no bits in common or that
5;; are disjoint are lowered into constant GEPs. Note that because this is a
6;; target-independent test, the GEP separator will lower the separated-off constant
7;; part to ptrtoint-based arithmetic.
8
9define void @testOrDoesntSplit(ptr %p) {
10; CHECK-LABEL: define void @testOrDoesntSplit(
11; CHECK-SAME: ptr [[P:%.*]]) {
12; CHECK-NEXT:    [[VAR:%.*]] = tail call i64 @foo()
13; CHECK-NEXT:    [[OFF:%.*]] = or i64 [[VAR]], 10
14; CHECK-NEXT:    [[Q:%.*]] = getelementptr i8, ptr [[P]], i64 [[OFF]]
15; CHECK-NEXT:    store i8 0, ptr [[Q]], align 1
16; CHECK-NEXT:    ret void
17;
18  %var = tail call i64 @foo()
19  %off = or i64 %var, 10
20  %q = getelementptr i8, ptr %p, i64 %off
21  store i8 0, ptr %q
22  ret void
23}
24
25; COM: The check for `or disjoint` removed the old hasNoBitsInCommon()
26; COM: check, ensure that failing to annotate an or with disjoint makes
27; COM: the optimization fail.
28define void @testNoBitsInCommonOrDoesntSplit(ptr %p) {
29; CHECK-LABEL: define void @testNoBitsInCommonOrDoesntSplit(
30; CHECK-SAME: ptr [[P:%.*]]) {
31; CHECK-NEXT:    [[VAR:%.*]] = tail call i64 @foo()
32; CHECK-NEXT:    [[VAR_HIGH:%.*]] = and i64 [[VAR]], -16
33; CHECK-NEXT:    [[OFF:%.*]] = or i64 [[VAR_HIGH]], 10
34; CHECK-NEXT:    [[Q:%.*]] = getelementptr i8, ptr [[P]], i64 [[OFF]]
35; CHECK-NEXT:    store i8 0, ptr [[Q]], align 1
36; CHECK-NEXT:    ret void
37;
38  %var = tail call i64 @foo()
39  %var.high = and i64 %var, -16
40  %off = or i64 %var.high, 10
41  %q = getelementptr i8, ptr %p, i64 %off
42  store i8 0, ptr %q
43  ret void
44}
45
46define void @testDisjointOrSplits(ptr %p) {
47; CHECK-LABEL: define void @testDisjointOrSplits(
48; CHECK-SAME: ptr [[P:%.*]]) {
49; CHECK-NEXT:    [[VAR:%.*]] = tail call i64 @foo()
50; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[P]] to i64
51; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[TMP1]], [[VAR]]
52; CHECK-NEXT:    [[TMP3:%.*]] = add i64 [[TMP2]], 10
53; CHECK-NEXT:    [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr
54; CHECK-NEXT:    store i8 0, ptr [[TMP4]], align 1
55; CHECK-NEXT:    ret void
56;
57  %var = tail call i64 @foo()
58  %off = or disjoint i64 %var, 10
59  %q = getelementptr i8, ptr %p, i64 %off
60  store i8 0, ptr %q
61  ret void
62}
63
64declare i64 @foo()
65