385 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s3 4declare void @llvm.assume(i1)5 6; Divisor is constant. X's range is known7 8define i8 @constant.divisor.v3(i8 %x) {9; CHECK-LABEL: @constant.divisor.v3(10; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 311; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])12; CHECK-NEXT: ret i8 013;14 %cmp.x.upper = icmp ult i8 %x, 315 call void @llvm.assume(i1 %cmp.x.upper)16 %div = udiv i8 %x, 317 ret i8 %div18}19define i8 @constant.divisor.v4(i8 %x) {20; CHECK-LABEL: @constant.divisor.v4(21; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 422; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])23; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], 324; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i825; CHECK-NEXT: ret i8 [[DIV]]26;27 %cmp.x.upper = icmp ult i8 %x, 428 call void @llvm.assume(i1 %cmp.x.upper)29 %div = udiv i8 %x, 330 ret i8 %div31}32define i8 @constant.divisor.x.range.v4(ptr %x.ptr) {33; CHECK-LABEL: @constant.divisor.x.range.v4(34; CHECK-NEXT: [[X:%.*]] = load i8, ptr [[X_PTR:%.*]], align 1, !range [[RNG0:![0-9]+]]35; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], 336; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i837; CHECK-NEXT: ret i8 [[DIV]]38;39 %x = load i8, ptr %x.ptr, !range !{ i8 0, i8 4 }40 %div = udiv i8 %x, 341 ret i8 %div42}43define i8 @constant.divisor.x.mask.v4(i8 %x) {44; CHECK-LABEL: @constant.divisor.x.mask.v4(45; CHECK-NEXT: [[X_MASKED:%.*]] = and i8 [[X:%.*]], 346; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X_MASKED]], 347; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i848; CHECK-NEXT: ret i8 [[DIV]]49;50 %x.masked = and i8 %x, 351 %div = udiv i8 %x.masked, 352 ret i8 %div53}54define i8 @constant.divisor.v5(i8 %x) {55; CHECK-LABEL: @constant.divisor.v5(56; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 557; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])58; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], 359; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i860; CHECK-NEXT: ret i8 [[DIV]]61;62 %cmp.x.upper = icmp ult i8 %x, 563 call void @llvm.assume(i1 %cmp.x.upper)64 %div = udiv i8 %x, 365 ret i8 %div66}67define i8 @constant.divisor.v6(i8 %x) {68; CHECK-LABEL: @constant.divisor.v6(69; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 670; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])71; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], 372; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i873; CHECK-NEXT: ret i8 [[DIV]]74;75 %cmp.x.upper = icmp ult i8 %x, 676 call void @llvm.assume(i1 %cmp.x.upper)77 %div = udiv i8 %x, 378 ret i8 %div79}80define i8 @constant.divisor.v7(i8 %x) {81; CHECK-LABEL: @constant.divisor.v7(82; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 783; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])84; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X]], 385; CHECK-NEXT: ret i8 [[DIV]]86;87 %cmp.x.upper = icmp ult i8 %x, 788 call void @llvm.assume(i1 %cmp.x.upper)89 %div = udiv i8 %x, 390 ret i8 %div91}92 93define i8 @constant.divisor.v6to8(i8 %x) {94; CHECK-LABEL: @constant.divisor.v6to8(95; CHECK-NEXT: [[CMP_X_LOWER:%.*]] = icmp samesign uge i8 [[X:%.*]], 696; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_LOWER]])97; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X]], 998; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])99; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X]], 3100; CHECK-NEXT: ret i8 2101;102 %cmp.x.lower = icmp uge i8 %x, 6103 call void @llvm.assume(i1 %cmp.x.lower)104 %cmp.x.upper = icmp ult i8 %x, 9105 call void @llvm.assume(i1 %cmp.x.upper)106 %div = udiv i8 %x, 3107 ret i8 %div108}109 110define i8 @constant.divisor.v9to11(i8 %x) {111; CHECK-LABEL: @constant.divisor.v9to11(112; CHECK-NEXT: [[CMP_X_LOWER:%.*]] = icmp samesign uge i8 [[X:%.*]], 9113; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_LOWER]])114; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X]], 12115; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])116; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X]], 3117; CHECK-NEXT: ret i8 3118;119 %cmp.x.lower = icmp uge i8 %x, 9120 call void @llvm.assume(i1 %cmp.x.lower)121 %cmp.x.upper = icmp ult i8 %x, 12122 call void @llvm.assume(i1 %cmp.x.upper)123 %div = udiv i8 %x, 3124 ret i8 %div125}126 127define i8 @constant.divisor.v12to14(i8 %x) {128; CHECK-LABEL: @constant.divisor.v12to14(129; CHECK-NEXT: [[CMP_X_LOWER:%.*]] = icmp samesign uge i8 [[X:%.*]], 12130; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_LOWER]])131; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X]], 15132; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])133; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X]], 3134; CHECK-NEXT: ret i8 4135;136 %cmp.x.lower = icmp uge i8 %x, 12137 call void @llvm.assume(i1 %cmp.x.lower)138 %cmp.x.upper = icmp ult i8 %x, 15139 call void @llvm.assume(i1 %cmp.x.upper)140 %div = udiv i8 %x, 3141 ret i8 %div142}143 144define i8 @constant.divisor.v6to11(i8 %x) {145; CHECK-LABEL: @constant.divisor.v6to11(146; CHECK-NEXT: [[CMP_X_LOWER:%.*]] = icmp samesign uge i8 [[X:%.*]], 6147; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_LOWER]])148; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X]], 12149; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])150; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X]], 3151; CHECK-NEXT: ret i8 [[DIV]]152;153 %cmp.x.lower = icmp uge i8 %x, 6154 call void @llvm.assume(i1 %cmp.x.lower)155 %cmp.x.upper = icmp ult i8 %x, 12156 call void @llvm.assume(i1 %cmp.x.upper)157 %div = udiv i8 %x, 3158 ret i8 %div159}160 161; Both are variable. Bounds are known162 163define i8 @variable.v3(i8 %x, i8 %y) {164; CHECK-LABEL: @variable.v3(165; CHECK-NEXT: [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 3166; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X]])167; CHECK-NEXT: [[CMP_Y_LOWER:%.*]] = icmp samesign uge i8 [[Y:%.*]], 3168; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_LOWER]])169; CHECK-NEXT: [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4170; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_UPPER]])171; CHECK-NEXT: ret i8 0172;173 %cmp.x = icmp ult i8 %x, 3174 call void @llvm.assume(i1 %cmp.x)175 %cmp.y.lower = icmp uge i8 %y, 3176 call void @llvm.assume(i1 %cmp.y.lower)177 %cmp.y.upper = icmp ule i8 %y, 4178 call void @llvm.assume(i1 %cmp.y.upper)179 %div = udiv i8 %x, %y180 ret i8 %div181}182define i8 @variable.v4(i8 %x, i8 %y) {183; CHECK-LABEL: @variable.v4(184; CHECK-NEXT: [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 4185; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X]])186; CHECK-NEXT: [[CMP_Y_LOWER:%.*]] = icmp samesign uge i8 [[Y:%.*]], 3187; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_LOWER]])188; CHECK-NEXT: [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4189; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_UPPER]])190; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], [[Y]]191; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i8192; CHECK-NEXT: ret i8 [[DIV]]193;194 %cmp.x = icmp ult i8 %x, 4195 call void @llvm.assume(i1 %cmp.x)196 %cmp.y.lower = icmp uge i8 %y, 3197 call void @llvm.assume(i1 %cmp.y.lower)198 %cmp.y.upper = icmp ule i8 %y, 4199 call void @llvm.assume(i1 %cmp.y.upper)200 %div = udiv i8 %x, %y201 ret i8 %div202}203define i8 @variable.v4.range(ptr %x.ptr, ptr %y.ptr) {204; CHECK-LABEL: @variable.v4.range(205; CHECK-NEXT: [[X:%.*]] = load i8, ptr [[X_PTR:%.*]], align 1, !range [[RNG0]]206; CHECK-NEXT: [[Y:%.*]] = load i8, ptr [[Y_PTR:%.*]], align 1, !range [[RNG1:![0-9]+]]207; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], [[Y]]208; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i8209; CHECK-NEXT: ret i8 [[DIV]]210;211 %x = load i8, ptr %x.ptr, !range !{ i8 0, i8 4 }212 %y = load i8, ptr %y.ptr, !range !{ i8 3, i8 5 }213 %div = udiv i8 %x, %y214 ret i8 %div215}216define i8 @variable.v5(i8 %x, i8 %y) {217; CHECK-LABEL: @variable.v5(218; CHECK-NEXT: [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 5219; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X]])220; CHECK-NEXT: [[CMP_Y_LOWER:%.*]] = icmp samesign uge i8 [[Y:%.*]], 3221; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_LOWER]])222; CHECK-NEXT: [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4223; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_UPPER]])224; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], [[Y]]225; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i8226; CHECK-NEXT: ret i8 [[DIV]]227;228 %cmp.x = icmp ult i8 %x, 5229 call void @llvm.assume(i1 %cmp.x)230 %cmp.y.lower = icmp uge i8 %y, 3231 call void @llvm.assume(i1 %cmp.y.lower)232 %cmp.y.upper = icmp ule i8 %y, 4233 call void @llvm.assume(i1 %cmp.y.upper)234 %div = udiv i8 %x, %y235 ret i8 %div236}237define i8 @variable.v6(i8 %x, i8 %y) {238; CHECK-LABEL: @variable.v6(239; CHECK-NEXT: [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 6240; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X]])241; CHECK-NEXT: [[CMP_Y_LOWER:%.*]] = icmp samesign uge i8 [[Y:%.*]], 3242; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_LOWER]])243; CHECK-NEXT: [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4244; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_UPPER]])245; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], [[Y]]246; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i8247; CHECK-NEXT: ret i8 [[DIV]]248;249 %cmp.x = icmp ult i8 %x, 6250 call void @llvm.assume(i1 %cmp.x)251 %cmp.y.lower = icmp uge i8 %y, 3252 call void @llvm.assume(i1 %cmp.y.lower)253 %cmp.y.upper = icmp ule i8 %y, 4254 call void @llvm.assume(i1 %cmp.y.upper)255 %div = udiv i8 %x, %y256 ret i8 %div257}258define i8 @variable.v7(i8 %x, i8 %y) {259; CHECK-LABEL: @variable.v7(260; CHECK-NEXT: [[CMP_X:%.*]] = icmp ult i8 [[X:%.*]], 7261; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X]])262; CHECK-NEXT: [[CMP_Y_LOWER:%.*]] = icmp samesign uge i8 [[Y:%.*]], 3263; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_LOWER]])264; CHECK-NEXT: [[CMP_Y_UPPER:%.*]] = icmp ule i8 [[Y]], 4265; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_Y_UPPER]])266; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X]], [[Y]]267; CHECK-NEXT: ret i8 [[DIV]]268;269 %cmp.x = icmp ult i8 %x, 7270 call void @llvm.assume(i1 %cmp.x)271 %cmp.y.lower = icmp uge i8 %y, 3272 call void @llvm.assume(i1 %cmp.y.lower)273 %cmp.y.upper = icmp ule i8 %y, 4274 call void @llvm.assume(i1 %cmp.y.upper)275 %div = udiv i8 %x, %y276 ret i8 %div277}278 279; Constant divisor280 281define i8 @large.divisor.v0(i8 %x) {282; CHECK-LABEL: @large.divisor.v0(283; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 127284; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])285; CHECK-NEXT: ret i8 0286;287 %cmp.x.upper = icmp ult i8 %x, 127288 call void @llvm.assume(i1 %cmp.x.upper)289 %div = udiv i8 %x, 127290 ret i8 %div291}292define i8 @large.divisor.v1(i8 %x) {293; CHECK-LABEL: @large.divisor.v1(294; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], -128295; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])296; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], 127297; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i8298; CHECK-NEXT: ret i8 [[DIV]]299;300 %cmp.x.upper = icmp ult i8 %x, 128301 call void @llvm.assume(i1 %cmp.x.upper)302 %div = udiv i8 %x, 127303 ret i8 %div304}305define i8 @large.divisor.v1.range(ptr %x.ptr) {306; CHECK-LABEL: @large.divisor.v1.range(307; CHECK-NEXT: [[X:%.*]] = load i8, ptr [[X_PTR:%.*]], align 1, !range [[RNG2:![0-9]+]]308; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], 127309; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i8310; CHECK-NEXT: ret i8 [[DIV]]311;312 %x = load i8, ptr %x.ptr, !range !{ i8 0, i8 128 }313 %div = udiv i8 %x, 127314 ret i8 %div315}316define i8 @large.divisor.v2.unbound.x(i8 %x) {317; CHECK-LABEL: @large.divisor.v2.unbound.x(318; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X:%.*]], 127319; CHECK-NEXT: ret i8 [[DIV]]320;321 %div = udiv i8 %x, 127322 ret i8 %div323}324 325define i8 @large.divisor.with.overflow.v0(i8 %x) {326; CHECK-LABEL: @large.divisor.with.overflow.v0(327; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], -128328; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])329; CHECK-NEXT: ret i8 0330;331 %cmp.x.upper = icmp ult i8 %x, 128332 call void @llvm.assume(i1 %cmp.x.upper)333 %div = udiv i8 %x, 128334 ret i8 %div335}336define i8 @large.divisor.with.overflow.v1(i8 %x) {337; CHECK-LABEL: @large.divisor.with.overflow.v1(338; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], -127339; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])340; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], -128341; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i8342; CHECK-NEXT: ret i8 [[DIV]]343;344 %cmp.x.upper = icmp ult i8 %x, 129345 call void @llvm.assume(i1 %cmp.x.upper)346 %div = udiv i8 %x, 128347 ret i8 %div348}349define i8 @large.divisor.with.overflow.v1.range(ptr %x.ptr) {350; CHECK-LABEL: @large.divisor.with.overflow.v1.range(351; CHECK-NEXT: [[X:%.*]] = load i8, ptr [[X_PTR:%.*]], align 1, !range [[RNG3:![0-9]+]]352; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X]], -128353; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i8354; CHECK-NEXT: ret i8 [[DIV]]355;356 %x = load i8, ptr %x.ptr, !range !{ i8 0, i8 129 }357 %div = udiv i8 %x, 128358 ret i8 %div359}360define i8 @large.divisor.with.overflow.v2.unbound.x(i8 %x) {361; CHECK-LABEL: @large.divisor.with.overflow.v2.unbound.x(362; CHECK-NEXT: [[DIV_CMP:%.*]] = icmp uge i8 [[X:%.*]], -128363; CHECK-NEXT: [[DIV:%.*]] = zext i1 [[DIV_CMP]] to i8364; CHECK-NEXT: ret i8 [[DIV]]365;366 %div = udiv i8 %x, 128367 ret i8 %div368}369 370define i8 @known_uge(i8 noundef %x) {371; CHECK-LABEL: @known_uge(372; CHECK-NEXT: [[CMP_X_UPPER:%.*]] = icmp ult i8 [[X:%.*]], 6373; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_UPPER]])374; CHECK-NEXT: [[CMP_X_LOWER:%.*]] = icmp samesign uge i8 [[X]], 3375; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_X_LOWER]])376; CHECK-NEXT: ret i8 1377;378 %cmp.x.upper = icmp ult i8 %x, 6379 call void @llvm.assume(i1 %cmp.x.upper)380 %cmp.x.lower = icmp uge i8 %x, 3381 call void @llvm.assume(i1 %cmp.x.lower)382 %div = udiv i8 %x, 3383 ret i8 %div384}385