; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 ; RUN: opt -passes=instcombine %s -S | FileCheck %s define ptr @pos_pow2_2(ptr %foo, i64 %x) { ; CHECK-LABEL: define ptr @pos_pow2_2( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]]) { ; CHECK-NEXT: [[IDX_MASK:%.*]] = and i64 [[X]], 1 ; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 [[IDX_MASK]] ; CHECK-NEXT: ret ptr [[P1]] ; %idx = srem i64 %x, 2 %p = getelementptr inbounds nuw i8, ptr %foo, i64 %idx ret ptr %p } define ptr @pos_pow2_4(ptr %foo, i64 %x) { ; CHECK-LABEL: define ptr @pos_pow2_4( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]]) { ; CHECK-NEXT: [[IDX_MASK:%.*]] = and i64 [[X]], 3 ; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 [[IDX_MASK]] ; CHECK-NEXT: ret ptr [[P1]] ; %idx = srem i64 %x, 4 %p = getelementptr inbounds nuw i8, ptr %foo, i64 %idx ret ptr %p } define ptr @pos_pow2_8(ptr %foo, i64 %x) { ; CHECK-LABEL: define ptr @pos_pow2_8( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]]) { ; CHECK-NEXT: [[IDX_MASK:%.*]] = and i64 [[X]], 7 ; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 [[IDX_MASK]] ; CHECK-NEXT: ret ptr [[P1]] ; %idx = srem i64 %x, 8 %p = getelementptr inbounds nuw i8, ptr %foo, i64 %idx ret ptr %p } define ptr @pos_not_i8(ptr %foo, i64 %x) { ; CHECK-LABEL: define ptr @pos_not_i8( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]]) { ; CHECK-NEXT: [[IDX1:%.*]] = and i64 [[X]], 3 ; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[FOO]], i64 [[IDX1]] ; CHECK-NEXT: ret ptr [[P2]] ; %idx = srem i64 %x, 4 %p = getelementptr inbounds nuw i32, ptr %foo, i64 %idx ret ptr %p } ; srem x, 1 is always 0, and mask is 0. GEP should be folded to %foo. define ptr @pos_pow2_1(ptr %foo, i64 %x) { ; CHECK-LABEL: define ptr @pos_pow2_1( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]]) { ; CHECK-NEXT: ret ptr [[FOO]] ; %idx = srem i64 %x, 1 %p = getelementptr inbounds nuw i8, ptr %foo, i64 %idx ret ptr %p } ; Non-power-of-two constant divisor define ptr @neg_non_pow2_6(ptr %foo, i64 %x) { ; CHECK-LABEL: define ptr @neg_non_pow2_6( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]]) { ; CHECK-NEXT: [[IDX:%.*]] = srem i64 [[X]], 6 ; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 [[IDX]] ; CHECK-NEXT: ret ptr [[P]] ; %idx = srem i64 %x, 6 %p = getelementptr inbounds nuw i8, ptr %foo, i64 %idx ret ptr %p } ; Missing 'no unsigned wrap' define ptr @neg_missing_nuw(ptr %foo, i64 %x) { ; CHECK-LABEL: define ptr @neg_missing_nuw( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]]) { ; CHECK-NEXT: [[IDX:%.*]] = srem i64 [[X]], 4 ; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 [[IDX]] ; CHECK-NEXT: ret ptr [[P]] ; %idx = srem i64 %x, 4 %p = getelementptr inbounds i8, ptr %foo, i64 %idx ret ptr %p } ; Missing 'inbounds' define ptr @neg_missing_inbounds(ptr %foo, i64 %x) { ; CHECK-LABEL: define ptr @neg_missing_inbounds( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]]) { ; CHECK-NEXT: [[IDX:%.*]] = srem i64 [[X]], 4 ; CHECK-NEXT: [[P:%.*]] = getelementptr nuw i8, ptr [[FOO]], i64 [[IDX]] ; CHECK-NEXT: ret ptr [[P]] ; %idx = srem i64 %x, 4 %p = getelementptr nuw i8, ptr %foo, i64 %idx ret ptr %p } define ptr @neg_nonconst_divisor(ptr %foo, i64 %x, i64 %d) { ; CHECK-LABEL: define ptr @neg_nonconst_divisor( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]], i64 [[D:%.*]]) { ; CHECK-NEXT: [[IDX:%.*]] = srem i64 [[X]], [[D]] ; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 [[IDX]] ; CHECK-NEXT: ret ptr [[P]] ; %idx = srem i64 %x, %d %p = getelementptr inbounds nuw i8, ptr %foo, i64 %idx ret ptr %p } declare void @use(i8) define ptr @neg_multi_use(ptr %foo, i64 %x) { ; CHECK-LABEL: define ptr @neg_multi_use( ; CHECK-SAME: ptr [[FOO:%.*]], i64 [[X:%.*]]) { ; CHECK-NEXT: [[IDX:%.*]] = srem i64 [[X]], 4 ; CHECK-NEXT: call void @use(i64 [[IDX]]) ; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 [[IDX]] ; CHECK-NEXT: ret ptr [[P]] ; %idx = srem i64 %x, 4 call void @use(i64 %idx) %p = getelementptr inbounds nuw i8, ptr %foo, i64 %idx ret ptr %p }