337 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 32; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 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 i649; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP0]]10; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP1]], i64 4011; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 412; CHECK-NEXT: ret void13;14entry:15 %add = add nsw i32 %a, 1016 %idx = sext i32 %add to i6417 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx18 store i32 %b, ptr %gep19 ret void20}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]], 527; CHECK-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i6428; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]29; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 430; CHECK-NEXT: ret i32 [[ADD]]31;32entry:33 %add = add nsw i32 %a, 534 %idx = sext i32 %add to i6435 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx36 store i32 %b, ptr %gep37 ret i32 %add38}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]], 1045; CHECK-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i6446; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]47; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 448; CHECK-NEXT: ret void49;50entry:51 %add = add i32 %a, 1052 %idx = sext i32 %add to i6453 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx54 store i32 %b, ptr %gep55 ret void56}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 i6464; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]65; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 466; CHECK-NEXT: ret void67;68entry:69 %add = add i32 %a, %b70 %idx = sext i32 %add to i6471 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx72 store i32 %b, ptr %gep73 ret void74}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 i6481; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP0]]82; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP1]], i64 4083; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 484; CHECK-NEXT: ret void85;86entry:87 %add = add nsw i32 %a, 1088 %idx = zext nneg i32 %add to i6489 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx90 store i32 %b, ptr %gep91 ret void92}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]], 1099; CHECK-NEXT: [[IDX:%.*]] = zext i32 [[ADD]] to i64100; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[IDX]]101; CHECK-NEXT: store i32 [[B]], ptr [[GEP]], align 4102; CHECK-NEXT: ret void103;104entry:105 %add = add nsw i32 %a, 10106 %idx = zext i32 %add to i64107 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx108 store i32 %b, ptr %gep109 ret void110}111 112define ptr @gep_inbounds_nuwaddlike(ptr %ptr, i64 %a, i64 %b) {113; CHECK-LABEL: define ptr @gep_inbounds_nuwaddlike(114; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {115; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[A]]116; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i64 [[B]]117; CHECK-NEXT: ret ptr [[GEP]]118;119 %add = or disjoint i64 %a, %b120 %gep = getelementptr inbounds nuw i32, ptr %ptr, i64 %add121 ret ptr %gep122}123 124define ptr @gep_inbounds_add_nuw(ptr %ptr, i64 %a, i64 %b) {125; CHECK-LABEL: define ptr @gep_inbounds_add_nuw(126; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {127; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[A]]128; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i64 [[B]]129; CHECK-NEXT: ret ptr [[GEP]]130;131 %add = add nuw i64 %a, %b132 %gep = getelementptr inbounds nuw i32, ptr %ptr, i64 %add133 ret ptr %gep134}135 136define ptr @gep_inbounds_add_nusw_nuw(ptr %ptr, i64 %a, i64 %b) {137; CHECK-LABEL: define ptr @gep_inbounds_add_nusw_nuw(138; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {139; CHECK-NEXT: [[TMP1:%.*]] = getelementptr nusw nuw i32, ptr [[PTR]], i64 [[A]]140; CHECK-NEXT: [[GEP:%.*]] = getelementptr nusw nuw i32, ptr [[TMP1]], i64 [[B]]141; CHECK-NEXT: ret ptr [[GEP]]142;143 %add = add nuw i64 %a, %b144 %gep = getelementptr nusw nuw i32, ptr %ptr, i64 %add145 ret ptr %gep146}147 148define ptr @gep_add_nuw(ptr %ptr, i64 %a, i64 %b) {149; CHECK-LABEL: define ptr @gep_add_nuw(150; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {151; CHECK-NEXT: [[TMP1:%.*]] = getelementptr nuw i32, ptr [[PTR]], i64 [[A]]152; CHECK-NEXT: [[GEP:%.*]] = getelementptr nuw i32, ptr [[TMP1]], i64 [[B]]153; CHECK-NEXT: ret ptr [[GEP]]154;155 %add = add nuw i64 %a, %b156 %gep = getelementptr nuw i32, ptr %ptr, i64 %add157 ret ptr %gep158}159 160define ptr @gep_inbounds_add_nsw_nonneg(ptr %ptr, i64 %a, i64 %b) {161; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_nonneg(162; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {163; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1164; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])165; CHECK-NEXT: [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1166; CHECK-NEXT: call void @llvm.assume(i1 [[B_NNEG]])167; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[A]]168; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP1]], i64 [[B]]169; CHECK-NEXT: ret ptr [[GEP]]170;171 %a.nneg = icmp sgt i64 %a, -1172 call void @llvm.assume(i1 %a.nneg)173 %b.nneg = icmp sgt i64 %b, -1174 call void @llvm.assume(i1 %b.nneg)175 %add = add nsw i64 %a, %b176 %gep = getelementptr inbounds i32, ptr %ptr, i64 %add177 ret ptr %gep178}179 180define ptr @gep_inbounds_add_nsw_not_nonneg1(ptr %ptr, i64 %a, i64 %b) {181; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_not_nonneg1(182; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {183; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1184; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])185; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]186; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]187; CHECK-NEXT: ret ptr [[GEP]]188;189 %a.nneg = icmp sgt i64 %a, -1190 call void @llvm.assume(i1 %a.nneg)191 %add = add nsw i64 %a, %b192 %gep = getelementptr inbounds i32, ptr %ptr, i64 %add193 ret ptr %gep194}195 196define ptr @gep_inbounds_add_nsw_not_nonneg2(ptr %ptr, i64 %a, i64 %b) {197; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_not_nonneg2(198; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {199; CHECK-NEXT: [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1200; CHECK-NEXT: call void @llvm.assume(i1 [[B_NNEG]])201; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]202; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]203; CHECK-NEXT: ret ptr [[GEP]]204;205 %b.nneg = icmp sgt i64 %b, -1206 call void @llvm.assume(i1 %b.nneg)207 %add = add nsw i64 %a, %b208 %gep = getelementptr inbounds i32, ptr %ptr, i64 %add209 ret ptr %gep210}211 212define ptr @gep_not_inbounds_add_nsw_nonneg(ptr %ptr, i64 %a, i64 %b) {213; CHECK-LABEL: define ptr @gep_not_inbounds_add_nsw_nonneg(214; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {215; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1216; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])217; CHECK-NEXT: [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1218; CHECK-NEXT: call void @llvm.assume(i1 [[B_NNEG]])219; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]220; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]221; CHECK-NEXT: ret ptr [[GEP]]222;223 %a.nneg = icmp sgt i64 %a, -1224 call void @llvm.assume(i1 %a.nneg)225 %b.nneg = icmp sgt i64 %b, -1226 call void @llvm.assume(i1 %b.nneg)227 %add = add nsw i64 %a, %b228 %gep = getelementptr i32, ptr %ptr, i64 %add229 ret ptr %gep230}231 232define ptr @gep_inbounds_add_not_nsw_nonneg(ptr %ptr, i64 %a, i64 %b) {233; CHECK-LABEL: define ptr @gep_inbounds_add_not_nsw_nonneg(234; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {235; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1236; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])237; CHECK-NEXT: [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1238; CHECK-NEXT: call void @llvm.assume(i1 [[B_NNEG]])239; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]240; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]241; CHECK-NEXT: ret ptr [[GEP]]242;243 %a.nneg = icmp sgt i64 %a, -1244 call void @llvm.assume(i1 %a.nneg)245 %b.nneg = icmp sgt i64 %b, -1246 call void @llvm.assume(i1 %b.nneg)247 %add = add i64 %a, %b248 %gep = getelementptr inbounds i32, ptr %ptr, i64 %add249 ret ptr %gep250}251 252define ptr @gep_inbounds_sext_add_nonneg(ptr %ptr, i32 %a) {253; CHECK-LABEL: define ptr @gep_inbounds_sext_add_nonneg(254; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {255; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1256; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])257; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[A]] to i64258; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[TMP1]]259; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 40260; CHECK-NEXT: ret ptr [[GEP]]261;262 %a.nneg = icmp sgt i32 %a, -1263 call void @llvm.assume(i1 %a.nneg)264 %add = add nsw i32 %a, 10265 %idx = sext i32 %add to i64266 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx267 ret ptr %gep268}269 270define ptr @gep_inbounds_sext_addlike_nonneg(ptr %ptr, i32 %a) {271; CHECK-LABEL: define ptr @gep_inbounds_sext_addlike_nonneg(272; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {273; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1274; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])275; CHECK-NEXT: [[IDX:%.*]] = zext nneg i32 [[A]] to i64276; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[IDX]]277; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds nuw i8, ptr [[GEP]], i64 40278; CHECK-NEXT: ret ptr [[GEP1]]279;280 %a.nneg = icmp sgt i32 %a, -1281 call void @llvm.assume(i1 %a.nneg)282 %add = or disjoint i32 %a, 10283 %idx = sext i32 %add to i64284 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx285 ret ptr %gep286}287 288define ptr @gep_inbounds_sext_add_not_nonneg_1(ptr %ptr, i32 %a) {289; CHECK-LABEL: define ptr @gep_inbounds_sext_add_not_nonneg_1(290; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {291; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1292; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])293; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[A]] to i64294; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]295; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 -40296; CHECK-NEXT: ret ptr [[GEP]]297;298 %a.nneg = icmp sgt i32 %a, -1299 call void @llvm.assume(i1 %a.nneg)300 %add = add nsw i32 %a, -10301 %idx = sext i32 %add to i64302 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx303 ret ptr %gep304}305 306define ptr @gep_inbounds_sext_add_not_nonneg_2(ptr %ptr, i32 %a) {307; CHECK-LABEL: define ptr @gep_inbounds_sext_add_not_nonneg_2(308; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {309; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[A]] to i64310; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]311; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 40312; CHECK-NEXT: ret ptr [[GEP]]313;314 %add = add nsw i32 %a, 10315 %idx = sext i32 %add to i64316 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx317 ret ptr %gep318}319 320define ptr @gep_not_inbounds_sext_add_nonneg(ptr %ptr, i32 %a) {321; CHECK-LABEL: define ptr @gep_not_inbounds_sext_add_nonneg(322; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {323; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1324; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])325; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[A]] to i64326; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]327; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 40328; CHECK-NEXT: ret ptr [[GEP]]329;330 %a.nneg = icmp sgt i32 %a, -1331 call void @llvm.assume(i1 %a.nneg)332 %add = add nsw i32 %a, 10333 %idx = sext i32 %add to i64334 %gep = getelementptr i32, ptr %ptr, i64 %idx335 ret ptr %gep336}337