259 lines · plain
1; RUN: opt --bpf-check-and-opt-ir -S -mtriple=bpf-pc-linux %s | FileCheck %s2 3; Test plan:4; @test1: x < umin(i64 a, i64 b)5; @test2: x < umax(i64 a, i64 b)6; @test3: x >= umin(i64 a, i64 b)7; @test4: x >= umax(i64 a, i64 b)8; @test5: umin(i64 a, i64 b) >= x9; @test6: x < smin(i64 a, i64 b)10; @test7: x < umin(i32 a, i32 b)11; @test8: x < zext i64 umin(i32 a, i32 b)12; @test9: x < sext i64 umin(i32 a, i32 b)13; @test10: check that umin belonging to the same loop is not touched14; @test11: check that nested loops are processed15 16define i32 @test1(i64 %a, i64 %b, i64 %x) {17entry:18 %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)19 br label %loop20loop:21 %cmp = icmp ult i64 %x, %min22 br i1 %cmp, label %loop, label %ret23ret: ret i32 024}25 26; CHECK: @test127; CHECK-NEXT: entry:28; CHECK-NEXT: br label %loop29; CHECK-EMPTY:30; CHECK-NEXT: loop:31; CHECK-NEXT: %0 = icmp ult i64 %x, %a32; CHECK-NEXT: %1 = icmp ult i64 %x, %b33; CHECK-NEXT: %2 = select i1 %0, i1 %1, i1 false34; CHECK-NEXT: br i1 %2, label %loop, label %ret35 36define i32 @test2(i64 %a, i64 %b, i64 %x) {37entry:38 %max = tail call i64 @llvm.umax.i64(i64 %a, i64 %b)39 br label %loop40loop:41 %cmp = icmp ult i64 %x, %max42 br i1 %cmp, label %loop, label %ret43ret: ret i32 044}45 46; CHECK: @test247; CHECK-NEXT: entry:48; CHECK-NEXT: br label %loop49; CHECK-EMPTY:50; CHECK-NEXT: loop:51; CHECK-NEXT: %0 = icmp ult i64 %x, %a52; CHECK-NEXT: %1 = icmp ult i64 %x, %b53; CHECK-NEXT: %2 = select i1 %0, i1 true, i1 %154; CHECK-NEXT: br i1 %2, label %loop, label %ret55 56define i32 @test3(i64 %a, i64 %b, i64 %x) {57entry:58 %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)59 br label %loop60loop:61 %cmp = icmp uge i64 %x, %min62 br i1 %cmp, label %loop, label %ret63ret: ret i32 064}65 66; CHECK: @test367; CHECK-NEXT: entry:68; CHECK-NEXT: br label %loop69; CHECK-EMPTY:70; CHECK-NEXT: loop:71; CHECK-NEXT: %0 = icmp uge i64 %x, %a72; CHECK-NEXT: %1 = icmp uge i64 %x, %b73; CHECK-NEXT: %2 = select i1 %0, i1 true, i1 %174; CHECK-NEXT: br i1 %2, label %loop, label %ret75 76define i32 @test4(i64 %a, i64 %b, i64 %x) {77entry:78 %max = tail call i64 @llvm.umax.i64(i64 %a, i64 %b)79 br label %loop80loop:81 %cmp = icmp uge i64 %x, %max82 br i1 %cmp, label %loop, label %ret83ret: ret i32 084}85 86; CHECK: @test487; CHECK-NEXT: entry:88; CHECK-NEXT: br label %loop89; CHECK-EMPTY:90; CHECK-NEXT: loop:91; CHECK-NEXT: %0 = icmp uge i64 %x, %a92; CHECK-NEXT: %1 = icmp uge i64 %x, %b93; CHECK-NEXT: %2 = select i1 %0, i1 %1, i1 false94; CHECK-NEXT: br i1 %2, label %loop, label %ret95 96define i32 @test5(i64 %a, i64 %b, i64 %x) {97entry:98 %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)99 br label %loop100loop:101 %cmp = icmp uge i64 %min, %x102 br i1 %cmp, label %loop, label %ret103ret: ret i32 0104}105 106; CHECK: @test5107; CHECK-NEXT: entry:108; CHECK-NEXT: br label %loop109; CHECK-EMPTY:110; CHECK-NEXT: loop:111; CHECK: %0 = icmp ule i64 %x, %a112; CHECK-NEXT: %1 = icmp ule i64 %x, %b113; CHECK-NEXT: %2 = select i1 %0, i1 %1, i1 false114; CHECK-NEXT: br i1 %2, label %loop, label %ret115 116define i32 @test6(i64 %a, i64 %b, i64 %x) {117entry:118 %min = tail call i64 @llvm.smin.i64(i64 %a, i64 %b)119 br label %loop120loop:121 %cmp = icmp slt i64 %x, %min122 br i1 %cmp, label %loop, label %ret123ret: ret i32 0124}125 126; CHECK: @test6127; CHECK-NEXT: entry:128; CHECK-NEXT: br label %loop129; CHECK-EMPTY:130; CHECK-NEXT: loop:131; CHECK: %0 = icmp slt i64 %x, %a132; CHECK-NEXT: %1 = icmp slt i64 %x, %b133; CHECK-NEXT: %2 = select i1 %0, i1 %1, i1 false134; CHECK-NEXT: br i1 %2, label %loop, label %ret135 136define i32 @test7(i32 %a, i32 %b, i32 %x) {137entry:138 %min = tail call i32 @llvm.umin.i32(i32 %a, i32 %b)139 br label %loop140loop:141 %cmp = icmp ult i32 %x, %min142 br i1 %cmp, label %loop, label %ret143ret: ret i32 0144}145 146; CHECK: @test7147; CHECK-NEXT: entry:148; CHECK-NEXT: br label %loop149; CHECK-EMPTY:150; CHECK-NEXT: loop:151; CHECK: %0 = icmp ult i32 %x, %a152; CHECK-NEXT: %1 = icmp ult i32 %x, %b153; CHECK-NEXT: %2 = select i1 %0, i1 %1, i1 false154; CHECK-NEXT: br i1 %2, label %loop, label %ret155 156define i32 @test8(i32 %a, i32 %b, i64 %x) {157entry:158 %min = tail call i32 @llvm.umin.i32(i32 %a, i32 %b)159 br label %loop160loop:161 %ext = zext i32 %min to i64162 %cmp = icmp ult i64 %x, %ext163 br i1 %cmp, label %loop, label %ret164ret: ret i32 0165}166 167; CHECK: @test8168; CHECK-NEXT: entry:169; CHECK-NEXT: br label %loop170; CHECK-EMPTY:171; CHECK-NEXT: loop:172; CHECK-NEXT: %0 = zext i32 %a to i64173; CHECK-NEXT: %1 = zext i32 %b to i64174; CHECK-NEXT: %2 = icmp ult i64 %x, %0175; CHECK-NEXT: %3 = icmp ult i64 %x, %1176; CHECK-NEXT: %4 = select i1 %2, i1 %3, i1 false177; CHECK-NEXT: br i1 %4, label %loop, label %ret178 179define i32 @test9(i32 %a, i32 %b, i64 %x) {180entry:181 %min = tail call i32 @llvm.umin.i32(i32 %a, i32 %b)182 br label %loop183loop:184 %ext = sext i32 %min to i64185 %cmp = icmp ult i64 %x, %ext186 br i1 %cmp, label %loop, label %ret187ret: ret i32 0188}189 190; CHECK: @test9191; CHECK-NEXT: entry:192; CHECK-NEXT: br label %loop193; CHECK-EMPTY:194; CHECK-NEXT: loop:195; CHECK-NEXT: %0 = sext i32 %a to i64196; CHECK-NEXT: %1 = sext i32 %b to i64197; CHECK-NEXT: %2 = icmp ult i64 %x, %0198; CHECK-NEXT: %3 = icmp ult i64 %x, %1199; CHECK-NEXT: %4 = select i1 %2, i1 %3, i1 false200; CHECK-NEXT: br i1 %4, label %loop, label %ret201 202; umin within the loop body is unchanged203define i32 @test10(i64 %a, i64 %b, i64 %x) {204entry:205 br label %loop206loop:207 %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)208 %cmp = icmp ult i64 %x, %min209 br i1 %cmp, label %loop, label %ret210ret: ret i32 0211}212 213; CHECK: @test10214; CHECK-NEXT: entry:215; CHECK-NEXT: br label %loop216; CHECK-EMPTY:217; CHECK-NEXT: loop:218; CHECK-NEXT: %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)219; CHECK-NEXT: %cmp = icmp ult i64 %x, %min220; CHECK-NEXT: br i1 %cmp, label %loop, label %ret221 222; umin from outer loop body is processed223define i32 @test11(i64 %a, i64 %b, i64 %x) {224entry:225 br label %loop226 227loop:228 %min = tail call i64 @llvm.umin.i64(i64 %a, i64 %b)229 br label %nested.loop230nested.loop:231 %cmp = icmp ult i64 %x, %min232 br i1 %cmp, label %nested.loop, label %loop233 234ret: ret i32 0235}236 237; CHECK: @test11238; CHECK-NEXT: entry:239; CHECK-NEXT: br label %loop240; CHECK-EMPTY:241; CHECK-NEXT: loop:242; CHECK-NEXT: br label %nested.loop243; CHECK-EMPTY:244; CHECK-NEXT: nested.loop:245; CHECK-NEXT: %0 = icmp ult i64 %x, %a246; CHECK-NEXT: %1 = icmp ult i64 %x, %b247; CHECK-NEXT: %2 = select i1 %0, i1 %1, i1 false248; CHECK-NEXT: br i1 %2, label %nested.loop, label %loop249 250declare i64 @llvm.umin.i64(i64, i64)251declare i64 @llvm.smin.i64(i64, i64)252declare i64 @llvm.umax.i64(i64, i64)253declare i64 @llvm.smax.i64(i64, i64)254 255declare i32 @llvm.umin.i32(i32, i32)256declare i32 @llvm.smin.i32(i32, i32)257declare i32 @llvm.umax.i32(i32, i32)258declare i32 @llvm.smax.i32(i32, i32)259