1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define void @test(ptr %ptr, i32 %a, i32 %b) {
5 ; CHECK-LABEL: define void @test(
6 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
8 ; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[A]] to i64
9 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP0]]
10 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 10
11 ; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 4
12 ; CHECK-NEXT: ret void
15 %add = add nsw i32 %a, 10
16 %idx = sext i32 %add to i64
17 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
18 store i32 %b, ptr %gep
22 define i32 @test_add_res_moreoneuse(ptr %ptr, i32 %a, i32 %b) {
23 ; CHECK-LABEL: define i32 @test_add_res_moreoneuse(
24 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
26 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 5
27 ; CHECK-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64
28 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]
29 ; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 4
30 ; CHECK-NEXT: ret i32 [[ADD]]
33 %add = add nsw i32 %a, 5
34 %idx = sext i32 %add to i64
35 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
36 store i32 %b, ptr %gep
40 define void @test_addop_nonsw_flag(ptr %ptr, i32 %a, i32 %b) {
41 ; CHECK-LABEL: define void @test_addop_nonsw_flag(
42 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
44 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], 10
45 ; CHECK-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64
46 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]
47 ; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 4
48 ; CHECK-NEXT: ret void
52 %idx = sext i32 %add to i64
53 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
54 store i32 %b, ptr %gep
58 define void @test_add_op2_not_constant(ptr %ptr, i32 %a, i32 %b) {
59 ; CHECK-LABEL: define void @test_add_op2_not_constant(
60 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
62 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], [[B]]
63 ; CHECK-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64
64 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]
65 ; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 4
66 ; CHECK-NEXT: ret void
70 %idx = sext i32 %add to i64
71 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
72 store i32 %b, ptr %gep
76 define void @test_zext_nneg(ptr %ptr, i32 %a, i32 %b) {
77 ; CHECK-LABEL: define void @test_zext_nneg(
78 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
80 ; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[A]] to i64
81 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP0]]
82 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 10
83 ; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 4
84 ; CHECK-NEXT: ret void
87 %add = add nsw i32 %a, 10
88 %idx = zext nneg i32 %add to i64
89 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
90 store i32 %b, ptr %gep
94 define void @test_zext_missing_nneg(ptr %ptr, i32 %a, i32 %b) {
95 ; CHECK-LABEL: define void @test_zext_missing_nneg(
96 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
98 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 10
99 ; CHECK-NEXT: [[IDX:%.*]] = zext i32 [[ADD]] to i64
100 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]
101 ; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 4
102 ; CHECK-NEXT: ret void
105 %add = add nsw i32 %a, 10
106 %idx = zext i32 %add to i64
107 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
108 store i32 %b, ptr %gep