1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define ptr @mul4(ptr %p, i64 %x) { 5; CHECK-LABEL: define ptr @mul4( 6; CHECK-SAME: ptr [[P:%.*]], i64 [[X:%.*]]) { 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[GEP_IDX:%.*]] = shl i64 [[X]], 4 9; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[GEP_IDX]] 10; CHECK-NEXT: ret ptr [[GEP]] 11; 12entry: 13 %mul = mul i64 %x, 4 14 %gep = getelementptr inbounds i32, ptr %p, i64 %mul 15 ret ptr %gep 16} 17 18define ptr @mul4_nuw(ptr %p, i64 %x) { 19; CHECK-LABEL: define ptr @mul4_nuw( 20; CHECK-SAME: ptr [[P:%.*]], i64 [[X:%.*]]) { 21; CHECK-NEXT: entry: 22; CHECK-NEXT: [[GEP_IDX:%.*]] = shl i64 [[X]], 4 23; CHECK-NEXT: [[GEP:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[GEP_IDX]] 24; CHECK-NEXT: ret ptr [[GEP]] 25; 26entry: 27 %mul = mul i64 %x, 4 28 %gep = getelementptr nuw i32, ptr %p, i64 %mul 29 ret ptr %gep 30} 31 32define ptr @mul5(ptr %p, i64 %x) { 33; CHECK-LABEL: define ptr @mul5( 34; CHECK-SAME: ptr [[P:%.*]], i64 [[X:%.*]]) { 35; CHECK-NEXT: entry: 36; CHECK-NEXT: [[GEP_IDX:%.*]] = mul i64 [[X]], 20 37; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[GEP_IDX]] 38; CHECK-NEXT: ret ptr [[GEP]] 39; 40entry: 41 %mul = mul i64 %x, 5 42 %gep = getelementptr inbounds i32, ptr %p, i64 %mul 43 ret ptr %gep 44} 45 46define ptr @noinbounds(ptr %p, i64 %x) { 47; CHECK-LABEL: define ptr @noinbounds( 48; CHECK-SAME: ptr [[P:%.*]], i64 [[X:%.*]]) { 49; CHECK-NEXT: entry: 50; CHECK-NEXT: [[GEP_IDX:%.*]] = mul i64 [[X]], 20 51; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 [[GEP_IDX]] 52; CHECK-NEXT: ret ptr [[GEP]] 53; 54entry: 55 %mul = mul i64 %x, 5 56 %gep = getelementptr i32, ptr %p, i64 %mul 57 ret ptr %gep 58} 59 60define ptr @usemul(ptr %p, i64 %x) { 61; CHECK-LABEL: define ptr @usemul( 62; CHECK-SAME: ptr [[P:%.*]], i64 [[X:%.*]]) { 63; CHECK-NEXT: entry: 64; CHECK-NEXT: [[MUL:%.*]] = mul i64 [[X]], 5 65; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[MUL]] 66; CHECK-NEXT: call void @use(i64 [[MUL]]) 67; CHECK-NEXT: ret ptr [[GEP]] 68; 69entry: 70 %mul = mul i64 %x, 5 71 %gep = getelementptr inbounds i32, ptr %p, i64 %mul 72 call void @use(i64 %mul) 73 ret ptr %gep 74} 75 76define void @multiple(ptr %p, i64 %x) { 77; CHECK-LABEL: define void @multiple( 78; CHECK-SAME: ptr [[P:%.*]], i64 [[X:%.*]]) { 79; CHECK-NEXT: entry: 80; CHECK-NEXT: [[MUL21:%.*]] = mul i64 [[X]], 20 81; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[MUL21]] 82; CHECK-NEXT: [[MUL20:%.*]] = mul i64 [[X]], 20 83; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[MUL20]] 84; CHECK-NEXT: call void @use2(ptr [[GEP3]], ptr [[GEP2]]) 85; CHECK-NEXT: ret void 86; 87entry: 88 %mul5 = mul i64 %x, 5 89 %gep1 = getelementptr inbounds i32, ptr %p, i64 %mul5 90 %mul20 = mul i64 %x, 20 91 %gep2 = getelementptr inbounds i8, ptr %p, i64 %mul20 92 call void @use2(ptr %gep1, ptr %gep2) 93 ret void 94} 95 96define void @multiplestore(ptr %p, i64 %x) { 97; CHECK-LABEL: define void @multiplestore( 98; CHECK-SAME: ptr [[P:%.*]], i64 [[X:%.*]]) { 99; CHECK-NEXT: entry: 100; CHECK-NEXT: [[MUL20:%.*]] = mul i64 [[X]], 20 101; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[MUL20]] 102; CHECK-NEXT: [[MUL21:%.*]] = mul i64 [[X]], 20 103; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[MUL21]] 104; CHECK-NEXT: store i32 0, ptr [[GEP2]], align 4 105; CHECK-NEXT: store i32 1, ptr [[GEP3]], align 4 106; CHECK-NEXT: ret void 107; 108entry: 109 %mul5 = mul i64 %x, 5 110 %gep1 = getelementptr inbounds i32, ptr %p, i64 %mul5 111 %mul20 = mul i64 %x, 20 112 %gep2 = getelementptr inbounds i8, ptr %p, i64 %mul20 113 store i32 0, ptr %gep1 114 store i32 1, ptr %gep2 115 ret void 116} 117 118declare void @use(i64) 119declare void @use2(ptr, ptr) 120