131ffdb56SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
231ffdb56SFlorian Hahn; RUN: opt -p argpromotion -S %s | FileCheck %s
331ffdb56SFlorian Hahn
431ffdb56SFlorian Hahntarget datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
531ffdb56SFlorian Hahn
631ffdb56SFlorian Hahn@f = dso_local global { i16, i64 } { i16 1, i64 0 }, align 8
731ffdb56SFlorian Hahn
831ffdb56SFlorian Hahn; Test case for https://github.com/llvm/llvm-project/issues/84807.
931ffdb56SFlorian Hahn
10bba4a1daSFlorian Hahn; Make sure the loads from @callee are not moved to @caller, as the store
11bba4a1daSFlorian Hahn; in %then may aliases to load from %q.
1231ffdb56SFlorian Hahn
1331ffdb56SFlorian Hahndefine i32 @caller1(i1 %c) {
1431ffdb56SFlorian Hahn; CHECK-LABEL: define i32 @caller1(
1531ffdb56SFlorian Hahn; CHECK-SAME: i1 [[C:%.*]]) {
1631ffdb56SFlorian Hahn; CHECK-NEXT:  entry:
17bba4a1daSFlorian Hahn; CHECK-NEXT:    call void @callee1(ptr noundef nonnull @f, i1 [[C]])
1831ffdb56SFlorian Hahn; CHECK-NEXT:    ret i32 0
1931ffdb56SFlorian Hahn;
2031ffdb56SFlorian Hahnentry:
2131ffdb56SFlorian Hahn  call void @callee1(ptr noundef nonnull @f, i1 %c)
2231ffdb56SFlorian Hahn  ret i32 0
2331ffdb56SFlorian Hahn}
2431ffdb56SFlorian Hahn
2531ffdb56SFlorian Hahndefine internal void @callee1(ptr nocapture noundef readonly %q, i1 %c) {
2631ffdb56SFlorian Hahn; CHECK-LABEL: define internal void @callee1(
27*29441e4fSNikita Popov; CHECK-SAME: ptr noundef readonly captures(none) [[Q:%.*]], i1 [[C:%.*]]) {
2831ffdb56SFlorian Hahn; CHECK-NEXT:  entry:
2931ffdb56SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[EXIT:%.*]]
3031ffdb56SFlorian Hahn; CHECK:       then:
3131ffdb56SFlorian Hahn; CHECK-NEXT:    store i16 123, ptr @f, align 8
3231ffdb56SFlorian Hahn; CHECK-NEXT:    br label [[EXIT]]
3331ffdb56SFlorian Hahn; CHECK:       exit:
34bba4a1daSFlorian Hahn; CHECK-NEXT:    [[Q_0_VAL:%.*]] = load i16, ptr [[Q]], align 8
35bba4a1daSFlorian Hahn; CHECK-NEXT:    [[GEP_8:%.*]] = getelementptr inbounds i8, ptr [[Q]], i64 8
36bba4a1daSFlorian Hahn; CHECK-NEXT:    [[Q_8_VAL:%.*]] = load i64, ptr [[GEP_8]], align 8
3731ffdb56SFlorian Hahn; CHECK-NEXT:    call void @use(i16 [[Q_0_VAL]], i64 [[Q_8_VAL]])
3831ffdb56SFlorian Hahn; CHECK-NEXT:    ret void
3931ffdb56SFlorian Hahn;
4031ffdb56SFlorian Hahnentry:
4131ffdb56SFlorian Hahn  br i1 %c, label %then, label %exit
4231ffdb56SFlorian Hahn
4331ffdb56SFlorian Hahnthen:
4431ffdb56SFlorian Hahn  store i16 123, ptr @f, align 8
4531ffdb56SFlorian Hahn  br label %exit
4631ffdb56SFlorian Hahn
4731ffdb56SFlorian Hahnexit:
4831ffdb56SFlorian Hahn  %l.0 = load i16, ptr %q, align 8
4931ffdb56SFlorian Hahn  %gep.8  = getelementptr inbounds i8, ptr %q, i64 8
5031ffdb56SFlorian Hahn  %l.1 = load i64, ptr %gep.8, align 8
5131ffdb56SFlorian Hahn  call void @use(i16 %l.0, i64 %l.1)
5231ffdb56SFlorian Hahn  ret void
5331ffdb56SFlorian Hahn
5431ffdb56SFlorian Hahn  uselistorder ptr %q, { 1, 0 }
5531ffdb56SFlorian Hahn}
5631ffdb56SFlorian Hahn
5731ffdb56SFlorian Hahn; Same as @caller1/callee2, but with default uselist order.
5831ffdb56SFlorian Hahndefine i32 @caller2(i1 %c) {
5931ffdb56SFlorian Hahn; CHECK-LABEL: define i32 @caller2(
6031ffdb56SFlorian Hahn; CHECK-SAME: i1 [[C:%.*]]) {
6131ffdb56SFlorian Hahn; CHECK-NEXT:  entry:
6231ffdb56SFlorian Hahn; CHECK-NEXT:    call void @callee2(ptr noundef nonnull @f, i1 [[C]])
6331ffdb56SFlorian Hahn; CHECK-NEXT:    ret i32 0
6431ffdb56SFlorian Hahn;
6531ffdb56SFlorian Hahnentry:
6631ffdb56SFlorian Hahn  call void @callee2(ptr noundef nonnull @f, i1 %c)
6731ffdb56SFlorian Hahn  ret i32 0
6831ffdb56SFlorian Hahn}
6931ffdb56SFlorian Hahn
7031ffdb56SFlorian Hahndefine internal void @callee2(ptr nocapture noundef readonly %q, i1 %c) {
7131ffdb56SFlorian Hahn; CHECK-LABEL: define internal void @callee2(
72*29441e4fSNikita Popov; CHECK-SAME: ptr noundef readonly captures(none) [[Q:%.*]], i1 [[C:%.*]]) {
7331ffdb56SFlorian Hahn; CHECK-NEXT:  entry:
7431ffdb56SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[EXIT:%.*]]
7531ffdb56SFlorian Hahn; CHECK:       then:
7631ffdb56SFlorian Hahn; CHECK-NEXT:    store i16 123, ptr @f, align 8
7731ffdb56SFlorian Hahn; CHECK-NEXT:    br label [[EXIT]]
7831ffdb56SFlorian Hahn; CHECK:       exit:
7931ffdb56SFlorian Hahn; CHECK-NEXT:    [[Q_0_VAL:%.*]] = load i16, ptr [[Q]], align 8
8031ffdb56SFlorian Hahn; CHECK-NEXT:    [[GEP_8:%.*]] = getelementptr inbounds i8, ptr [[Q]], i64 8
8131ffdb56SFlorian Hahn; CHECK-NEXT:    [[Q_8_VAL:%.*]] = load i64, ptr [[GEP_8]], align 8
8231ffdb56SFlorian Hahn; CHECK-NEXT:    call void @use(i16 [[Q_0_VAL]], i64 [[Q_8_VAL]])
8331ffdb56SFlorian Hahn; CHECK-NEXT:    ret void
8431ffdb56SFlorian Hahn;
8531ffdb56SFlorian Hahnentry:
8631ffdb56SFlorian Hahn  br i1 %c, label %then, label %exit
8731ffdb56SFlorian Hahn
8831ffdb56SFlorian Hahnthen:
8931ffdb56SFlorian Hahn  store i16 123, ptr @f, align 8
9031ffdb56SFlorian Hahn  br label %exit
9131ffdb56SFlorian Hahn
9231ffdb56SFlorian Hahnexit:
9331ffdb56SFlorian Hahn  %l.0 = load i16, ptr %q, align 8
9431ffdb56SFlorian Hahn  %gep.8  = getelementptr inbounds i8, ptr %q, i64 8
9531ffdb56SFlorian Hahn  %l.1 = load i64, ptr %gep.8, align 8
9631ffdb56SFlorian Hahn  call void @use(i16 %l.0, i64 %l.1)
9731ffdb56SFlorian Hahn  ret void
9831ffdb56SFlorian Hahn}
9931ffdb56SFlorian Hahn
10031ffdb56SFlorian Hahndeclare void @use(i16, i64)
101