1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define i32* @test1a(i32* %p, i32* %q) { 5; CHECK-LABEL: @test1a( 6; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P:%.*]], [[Q:%.*]] 7; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i32* [[P]], i32* [[Q]] 8; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i32, i32* [[SELECT_V]], i64 4 9; CHECK-NEXT: ret i32* [[SELECT]] 10; 11 %gep1 = getelementptr i32, i32* %p, i64 4 12 %gep2 = getelementptr i32, i32* %q, i64 4 13 %cmp = icmp ugt i32* %p, %q 14 %select = select i1 %cmp, i32* %gep1, i32* %gep2 15 ret i32* %select 16} 17 18define i32* @test1b(i32* %p, i32* %q) { 19; CHECK-LABEL: @test1b( 20; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P:%.*]], [[Q:%.*]] 21; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i32* [[P]], i32* [[Q]] 22; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i32, i32* [[SELECT_V]], i64 4 23; CHECK-NEXT: ret i32* [[SELECT]] 24; 25 %gep1 = getelementptr inbounds i32, i32* %p, i64 4 26 %gep2 = getelementptr i32, i32* %q, i64 4 27 %cmp = icmp ugt i32* %p, %q 28 %select = select i1 %cmp, i32* %gep1, i32* %gep2 29 ret i32* %select 30} 31 32define i32* @test1c(i32* %p, i32* %q) { 33; CHECK-LABEL: @test1c( 34; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P:%.*]], [[Q:%.*]] 35; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i32* [[P]], i32* [[Q]] 36; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i32, i32* [[SELECT_V]], i64 4 37; CHECK-NEXT: ret i32* [[SELECT]] 38; 39 %gep1 = getelementptr i32, i32* %p, i64 4 40 %gep2 = getelementptr inbounds i32, i32* %q, i64 4 41 %cmp = icmp ugt i32* %p, %q 42 %select = select i1 %cmp, i32* %gep1, i32* %gep2 43 ret i32* %select 44} 45 46define i32* @test1d(i32* %p, i32* %q) { 47; CHECK-LABEL: @test1d( 48; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32* [[P:%.*]], [[Q:%.*]] 49; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i32* [[P]], i32* [[Q]] 50; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds i32, i32* [[SELECT_V]], i64 4 51; CHECK-NEXT: ret i32* [[SELECT]] 52; 53 %gep1 = getelementptr inbounds i32, i32* %p, i64 4 54 %gep2 = getelementptr inbounds i32, i32* %q, i64 4 55 %cmp = icmp ugt i32* %p, %q 56 %select = select i1 %cmp, i32* %gep1, i32* %gep2 57 ret i32* %select 58} 59 60define i32* @test2(i32* %p, i64 %x, i64 %y) { 61; CHECK-LABEL: @test2( 62; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]] 63; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], i64 [[X]], i64 [[Y]] 64; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 [[SELECT_V]] 65; CHECK-NEXT: ret i32* [[SELECT]] 66; 67 %gep1 = getelementptr inbounds i32, i32* %p, i64 %x 68 %gep2 = getelementptr inbounds i32, i32* %p, i64 %y 69 %cmp = icmp ugt i64 %x, %y 70 %select = select i1 %cmp, i32* %gep1, i32* %gep2 71 ret i32* %select 72} 73 74; Three (or more) operand GEPs are currently expected to not be optimised, 75; though they could be in principle. 76 77define i32* @test3a([4 x i32]* %p, i64 %x, i64 %y) { 78; CHECK-LABEL: @test3a( 79; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[P:%.*]], i64 2, i64 [[X:%.*]] 80; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[P]], i64 2, i64 [[Y:%.*]] 81; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y]] 82; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32* [[GEP1]], i32* [[GEP2]] 83; CHECK-NEXT: ret i32* [[SELECT]] 84; 85 %gep1 = getelementptr inbounds [4 x i32], [4 x i32]* %p, i64 2, i64 %x 86 %gep2 = getelementptr inbounds [4 x i32], [4 x i32]* %p, i64 2, i64 %y 87 %cmp = icmp ugt i64 %x, %y 88 %select = select i1 %cmp, i32* %gep1, i32* %gep2 89 ret i32* %select 90} 91 92define i32* @test3b([4 x i32]* %p, i32* %q, i64 %x, i64 %y) { 93; CHECK-LABEL: @test3b( 94; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[P:%.*]], i64 [[X:%.*]], i64 2 95; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, i32* [[Q:%.*]], i64 [[X]] 96; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]] 97; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32* [[GEP1]], i32* [[GEP2]] 98; CHECK-NEXT: ret i32* [[SELECT]] 99; 100 %gep1 = getelementptr inbounds [4 x i32], [4 x i32]* %p, i64 %x, i64 2 101 %gep2 = getelementptr inbounds i32, i32* %q, i64 %x 102 %cmp = icmp ugt i64 %x, %y 103 %select = select i1 %cmp, i32* %gep1, i32* %gep2 104 ret i32* %select 105} 106 107define i32* @test3c(i32* %p, [4 x i32]* %q, i64 %x, i64 %y) { 108; CHECK-LABEL: @test3c( 109; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 [[X:%.*]] 110; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [4 x i32], [4 x i32]* [[Q:%.*]], i64 [[X]], i64 2 111; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]] 112; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32* [[GEP1]], i32* [[GEP2]] 113; CHECK-NEXT: ret i32* [[SELECT]] 114; 115 %gep1 = getelementptr inbounds i32, i32* %p, i64 %x 116 %gep2 = getelementptr inbounds [4 x i32], [4 x i32]* %q, i64 %x, i64 2 117 %cmp = icmp ugt i64 %x, %y 118 %select = select i1 %cmp, i32* %gep1, i32* %gep2 119 ret i32* %select 120} 121 122; Shouldn't be optimised as it would mean introducing an extra select 123 124define i32* @test4(i32* %p, i32* %q, i64 %x, i64 %y) { 125; CHECK-LABEL: @test4( 126; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 [[X:%.*]] 127; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, i32* [[Q:%.*]], i64 [[Y:%.*]] 128; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X]], [[Y]] 129; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32* [[GEP1]], i32* [[GEP2]] 130; CHECK-NEXT: ret i32* [[SELECT]] 131; 132 %gep1 = getelementptr inbounds i32, i32* %p, i64 %x 133 %gep2 = getelementptr inbounds i32, i32* %q, i64 %y 134 %cmp = icmp ugt i64 %x, %y 135 %select = select i1 %cmp, i32* %gep1, i32* %gep2 136 ret i32* %select 137} 138 139