321 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define ptr @test1a(ptr %p, ptr %q) {5; CHECK-LABEL: @test1a(6; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[P:%.*]], [[Q:%.*]]7; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], ptr [[P]], ptr [[Q]]8; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i8, ptr [[SELECT_V]], i64 169; CHECK-NEXT: ret ptr [[SELECT]]10;11 %gep1 = getelementptr i32, ptr %p, i64 412 %gep2 = getelementptr i32, ptr %q, i64 413 %cmp = icmp ugt ptr %p, %q14 %select = select i1 %cmp, ptr %gep1, ptr %gep215 ret ptr %select16}17 18define ptr @test1b(ptr %p, ptr %q) {19; CHECK-LABEL: @test1b(20; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[P:%.*]], [[Q:%.*]]21; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], ptr [[P]], ptr [[Q]]22; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i8, ptr [[SELECT_V]], i64 1623; CHECK-NEXT: ret ptr [[SELECT]]24;25 %gep1 = getelementptr inbounds i32, ptr %p, i64 426 %gep2 = getelementptr i32, ptr %q, i64 427 %cmp = icmp ugt ptr %p, %q28 %select = select i1 %cmp, ptr %gep1, ptr %gep229 ret ptr %select30}31 32define ptr @test1c(ptr %p, ptr %q) {33; CHECK-LABEL: @test1c(34; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[P:%.*]], [[Q:%.*]]35; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], ptr [[P]], ptr [[Q]]36; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i8, ptr [[SELECT_V]], i64 1637; CHECK-NEXT: ret ptr [[SELECT]]38;39 %gep1 = getelementptr i32, ptr %p, i64 440 %gep2 = getelementptr inbounds i32, ptr %q, i64 441 %cmp = icmp ugt ptr %p, %q42 %select = select i1 %cmp, ptr %gep1, ptr %gep243 ret ptr %select44}45 46define ptr @test1d(ptr %p, ptr %q) {47; CHECK-LABEL: @test1d(48; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[P:%.*]], [[Q:%.*]]49; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], ptr [[P]], ptr [[Q]]50; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds nuw i8, ptr [[SELECT_V]], i64 1651; CHECK-NEXT: ret ptr [[SELECT]]52;53 %gep1 = getelementptr inbounds i32, ptr %p, i64 454 %gep2 = getelementptr inbounds i32, ptr %q, i64 455 %cmp = icmp ugt ptr %p, %q56 %select = select i1 %cmp, ptr %gep1, ptr %gep257 ret ptr %select58}59 60define ptr @test2(ptr %p, i64 %x, i64 %y) {61; CHECK-LABEL: @test2(62; CHECK-NEXT: [[SELECT_V:%.*]] = call i64 @llvm.umax.i64(i64 [[X:%.*]], i64 [[Y:%.*]])63; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[SELECT_V]]64; CHECK-NEXT: ret ptr [[SELECT]]65;66 %gep1 = getelementptr inbounds i32, ptr %p, i64 %x67 %gep2 = getelementptr inbounds i32, ptr %p, i64 %y68 %cmp = icmp ugt i64 %x, %y69 %select = select i1 %cmp, ptr %gep1, ptr %gep270 ret ptr %select71}72 73; PR5018374define ptr @test2a(ptr %p, i64 %x, i64 %y) {75; CHECK-LABEL: @test2a(76; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]77; CHECK-NEXT: [[SELECT_IDX:%.*]] = select i1 [[CMP]], i64 [[X]], i64 078; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[SELECT_IDX]]79; CHECK-NEXT: ret ptr [[SELECT]]80;81 %gep = getelementptr inbounds i32, ptr %p, i64 %x82 %cmp = icmp ugt i64 %x, %y83 %select = select i1 %cmp, ptr %gep, ptr %p84 ret ptr %select85}86 87define ptr @test2a_nusw(ptr %p, i64 %x, i64 %y) {88; CHECK-LABEL: @test2a_nusw(89; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]90; CHECK-NEXT: [[SELECT_IDX:%.*]] = select i1 [[CMP]], i64 [[X]], i64 091; CHECK-NEXT: [[SELECT:%.*]] = getelementptr nusw i32, ptr [[P:%.*]], i64 [[SELECT_IDX]]92; CHECK-NEXT: ret ptr [[SELECT]]93;94 %gep = getelementptr nusw i32, ptr %p, i64 %x95 %cmp = icmp ugt i64 %x, %y96 %select = select i1 %cmp, ptr %gep, ptr %p97 ret ptr %select98}99 100define ptr @test2a_nuw(ptr %p, i64 %x, i64 %y) {101; CHECK-LABEL: @test2a_nuw(102; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]103; CHECK-NEXT: [[SELECT_IDX:%.*]] = select i1 [[CMP]], i64 [[X]], i64 0104; CHECK-NEXT: [[SELECT:%.*]] = getelementptr nuw i32, ptr [[P:%.*]], i64 [[SELECT_IDX]]105; CHECK-NEXT: ret ptr [[SELECT]]106;107 %gep = getelementptr nuw i32, ptr %p, i64 %x108 %cmp = icmp ugt i64 %x, %y109 %select = select i1 %cmp, ptr %gep, ptr %p110 ret ptr %select111}112 113; PR50183114define ptr @test2b(ptr %p, i64 %x, i64 %y) {115; CHECK-LABEL: @test2b(116; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]117; CHECK-NEXT: [[SELECT_IDX:%.*]] = select i1 [[CMP]], i64 0, i64 [[X]]118; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[SELECT_IDX]]119; CHECK-NEXT: ret ptr [[SELECT]]120;121 %gep = getelementptr inbounds i32, ptr %p, i64 %x122 %cmp = icmp ugt i64 %x, %y123 %select = select i1 %cmp, ptr %p, ptr %gep124 ret ptr %select125}126 127; PR51069128define ptr @test2c(ptr %p, i64 %x, i64 %y) {129; CHECK-LABEL: @test2c(130; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[X:%.*]]131; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]]132; CHECK-NEXT: [[SEL_IDX:%.*]] = select i1 [[ICMP]], i64 0, i64 24133; CHECK-NEXT: [[SEL:%.*]] = getelementptr inbounds nuw i8, ptr [[GEP1]], i64 [[SEL_IDX]]134; CHECK-NEXT: ret ptr [[SEL]]135;136 %gep1 = getelementptr inbounds i32, ptr %p, i64 %x137 %gep2 = getelementptr inbounds i32, ptr %gep1, i64 6138 %icmp = icmp ugt i64 %x, %y139 %sel = select i1 %icmp, ptr %gep1, ptr %gep2140 ret ptr %sel141}142 143; PR51069144define ptr @test2d(ptr %p, i64 %x, i64 %y) {145; CHECK-LABEL: @test2d(146; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[X:%.*]]147; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]]148; CHECK-NEXT: [[SEL_IDX:%.*]] = select i1 [[ICMP]], i64 24, i64 0149; CHECK-NEXT: [[SEL:%.*]] = getelementptr inbounds nuw i8, ptr [[GEP1]], i64 [[SEL_IDX]]150; CHECK-NEXT: ret ptr [[SEL]]151;152 %gep1 = getelementptr inbounds i32, ptr %p, i64 %x153 %gep2 = getelementptr inbounds i32, ptr %gep1, i64 6154 %icmp = icmp ugt i64 %x, %y155 %sel = select i1 %icmp, ptr %gep2, ptr %gep1156 ret ptr %sel157}158 159; Three (or more) operand GEPs are currently expected to not be optimised,160; though they could be in principle.161 162define ptr @test3a(ptr %p, i64 %x, i64 %y) {163; CHECK-LABEL: @test3a(164; CHECK-NEXT: [[GEP1_SPLIT:%.*]] = getelementptr inbounds nuw i8, ptr [[P:%.*]], i64 32165; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[GEP1_SPLIT]], i64 [[X:%.*]]166; CHECK-NEXT: [[GEP2_SPLIT:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 32167; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[GEP2_SPLIT]], i64 [[Y:%.*]]168; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y]]169; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[GEP1]], ptr [[GEP2]]170; CHECK-NEXT: ret ptr [[SELECT]]171;172 %gep1 = getelementptr inbounds [4 x i32], ptr %p, i64 2, i64 %x173 %gep2 = getelementptr inbounds [4 x i32], ptr %p, i64 2, i64 %y174 %cmp = icmp ugt i64 %x, %y175 %select = select i1 %cmp, ptr %gep1, ptr %gep2176 ret ptr %select177}178 179define ptr @test3b(ptr %p, ptr %q, i64 %x, i64 %y) {180; CHECK-LABEL: @test3b(181; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]182; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[GEP1:%.*]], ptr [[GEP2:%.*]]183; CHECK-NEXT: [[SELECT_V:%.*]] = getelementptr inbounds nuw i8, ptr [[SELECT]], i64 32184; CHECK-NEXT: [[SELECT1:%.*]] = getelementptr inbounds i32, ptr [[SELECT_V]], i64 [[X]]185; CHECK-NEXT: ret ptr [[SELECT1]]186;187 %gep1 = getelementptr inbounds [4 x i32], ptr %p, i64 2, i64 %x188 %gep2 = getelementptr inbounds [4 x i32], ptr %q, i64 2, i64 %x189 %cmp = icmp ugt i64 %x, %y190 %select = select i1 %cmp, ptr %gep1, ptr %gep2191 ret ptr %select192}193 194define ptr @test3c(ptr %p, ptr %q, i64 %x, i64 %y) {195; CHECK-LABEL: @test3c(196; CHECK-NEXT: [[GEP1_SPLIT:%.*]] = getelementptr inbounds [4 x i32], ptr [[P:%.*]], i64 [[X:%.*]]197; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds nuw i8, ptr [[GEP1_SPLIT]], i64 8198; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[Q:%.*]], i64 [[X]]199; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]]200; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[GEP1]], ptr [[GEP2]]201; CHECK-NEXT: ret ptr [[SELECT]]202;203 %gep1 = getelementptr inbounds [4 x i32], ptr %p, i64 %x, i64 2204 %gep2 = getelementptr inbounds i32, ptr %q, i64 %x205 %cmp = icmp ugt i64 %x, %y206 %select = select i1 %cmp, ptr %gep1, ptr %gep2207 ret ptr %select208}209 210define ptr @test3d(ptr %p, ptr %q, i64 %x, i64 %y) {211; CHECK-LABEL: @test3d(212; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[X:%.*]]213; CHECK-NEXT: [[GEP2_SPLIT:%.*]] = getelementptr inbounds [4 x i32], ptr [[Q:%.*]], i64 [[X]]214; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds nuw i8, ptr [[GEP2_SPLIT]], i64 8215; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]]216; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[GEP1]], ptr [[GEP2]]217; CHECK-NEXT: ret ptr [[SELECT]]218;219 %gep1 = getelementptr inbounds i32, ptr %p, i64 %x220 %gep2 = getelementptr inbounds [4 x i32], ptr %q, i64 %x, i64 2221 %cmp = icmp ugt i64 %x, %y222 %select = select i1 %cmp, ptr %gep1, ptr %gep2223 ret ptr %select224}225 226; Shouldn't be optimised as it would mean introducing an extra select227 228define ptr @test4(ptr %p, ptr %q, i64 %x, i64 %y) {229; CHECK-LABEL: @test4(230; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[X:%.*]]231; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[Q:%.*]], i64 [[Y:%.*]]232; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y]]233; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[GEP1]], ptr [[GEP2]]234; CHECK-NEXT: ret ptr [[SELECT]]235;236 %gep1 = getelementptr inbounds i32, ptr %p, i64 %x237 %gep2 = getelementptr inbounds i32, ptr %q, i64 %y238 %cmp = icmp ugt i64 %x, %y239 %select = select i1 %cmp, ptr %gep1, ptr %gep2240 ret ptr %select241}242 243; We cannot create a select with a vector condition but scalar operands.244 245define <2 x ptr> @test5(ptr %p1, ptr %p2, <2 x i64> %idx, <2 x i1> %cc) {246; CHECK-LABEL: @test5(247; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, ptr [[P1:%.*]], <2 x i64> [[IDX:%.*]]248; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i64, ptr [[P2:%.*]], <2 x i64> [[IDX]]249; CHECK-NEXT: [[SELECT:%.*]] = select <2 x i1> [[CC:%.*]], <2 x ptr> [[GEP1]], <2 x ptr> [[GEP2]]250; CHECK-NEXT: ret <2 x ptr> [[SELECT]]251;252 %gep1 = getelementptr i64, ptr %p1, <2 x i64> %idx253 %gep2 = getelementptr i64, ptr %p2, <2 x i64> %idx254 %select = select <2 x i1> %cc, <2 x ptr> %gep1, <2 x ptr> %gep2255 ret <2 x ptr> %select256}257 258; PR51069 - multiple uses259define ptr @test6(ptr %p, i64 %x, i64 %y) {260; CHECK-LABEL: @test6(261; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[X:%.*]]262; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]]263; CHECK-NEXT: [[SEL_IDX:%.*]] = select i1 [[ICMP]], i64 [[Y]], i64 0264; CHECK-NEXT: [[SEL:%.*]] = getelementptr inbounds i32, ptr [[GEP1]], i64 [[SEL_IDX]]265; CHECK-NEXT: call void @use_i32p(ptr [[GEP1]])266; CHECK-NEXT: ret ptr [[SEL]]267;268 %gep1 = getelementptr inbounds i32, ptr %p, i64 %x269 %gep2 = getelementptr inbounds i32, ptr %gep1, i64 %y270 %icmp = icmp ugt i64 %x, %y271 %sel = select i1 %icmp, ptr %gep2, ptr %gep1272 call void @use_i32p(ptr %gep1)273 ret ptr %sel274}275declare void @use_i32p(ptr)276 277; We cannot create a select-with-idx with a vector condition but scalar idx.278 279define <2 x ptr> @test7(<2 x ptr> %p1, i64 %idx, <2 x i1> %cc) {280; CHECK-LABEL: @test7(281; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, <2 x ptr> [[P1:%.*]], i64 [[IDX:%.*]]282; CHECK-NEXT: [[SELECT:%.*]] = select <2 x i1> [[CC:%.*]], <2 x ptr> [[P1]], <2 x ptr> [[GEP]]283; CHECK-NEXT: ret <2 x ptr> [[SELECT]]284;285 %gep = getelementptr i64, <2 x ptr> %p1, i64 %idx286 %select = select <2 x i1> %cc, <2 x ptr> %p1, <2 x ptr> %gep287 ret <2 x ptr> %select288}289 290define ptr @ptr_eq_replace_freeze1(ptr %p, ptr %q) {291; CHECK-LABEL: @ptr_eq_replace_freeze1(292; CHECK-NEXT: [[Q_FR:%.*]] = freeze ptr [[Q:%.*]]293; CHECK-NEXT: [[Q_FR1:%.*]] = freeze ptr [[Q1:%.*]]294; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[Q_FR]], [[Q_FR1]]295; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[Q_FR]], ptr [[Q_FR1]]296; CHECK-NEXT: ret ptr [[SELECT]]297;298 %p.fr = freeze ptr %p299 %q.fr = freeze ptr %q300 %cmp = icmp eq ptr %p.fr, %q.fr301 %select = select i1 %cmp, ptr %p.fr, ptr %q.fr302 ret ptr %select303}304 305define ptr @ptr_eq_replace_freeze2(ptr %p, ptr %q) {306; CHECK-LABEL: @ptr_eq_replace_freeze2(307; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P:%.*]]308; CHECK-NEXT: [[P_FR1:%.*]] = freeze ptr [[P1:%.*]]309; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P_FR1]], [[P_FR]]310; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], ptr [[P_FR1]], ptr [[P_FR]]311; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i8, ptr [[SELECT_V]], i64 16312; CHECK-NEXT: ret ptr [[SELECT]]313;314 %gep1 = getelementptr i32, ptr %p, i64 4315 %gep2 = getelementptr i32, ptr %q, i64 4316 %cmp = icmp eq ptr %p, %q317 %cmp.fr = freeze i1 %cmp318 %select = select i1 %cmp.fr, ptr %gep1, ptr %gep2319 ret ptr %select320}321