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 3 4define void @test(ptr %ptr, i32 %a, i32 %b) { 5; CHECK-LABEL: define void @test( 6; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { 7; CHECK-NEXT: entry: 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 13; 14entry: 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 19 ret void 20} 21 22define 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:%.*]]) { 25; CHECK-NEXT: entry: 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]] 31; 32entry: 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 37 ret i32 %add 38} 39 40define 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:%.*]]) { 43; CHECK-NEXT: entry: 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 49; 50entry: 51 %add = add i32 %a, 10 52 %idx = sext i32 %add to i64 53 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx 54 store i32 %b, ptr %gep 55 ret void 56} 57 58define 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:%.*]]) { 61; CHECK-NEXT: entry: 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 67; 68entry: 69 %add = add i32 %a, %b 70 %idx = sext i32 %add to i64 71 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx 72 store i32 %b, ptr %gep 73 ret void 74} 75 76define 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:%.*]]) { 79; CHECK-NEXT: entry: 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 85; 86entry: 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 91 ret void 92} 93 94define 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:%.*]]) { 97; CHECK-NEXT: entry: 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 103; 104entry: 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 109 ret void 110} 111