317 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use8(i8)5 6declare void @use1(i1)7declare void @llvm.assume(i1)8 9define i1 @t0(i8 %base, i8 %offset) {10; CHECK-LABEL: @t0(11; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]12; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])13; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]14; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]15; CHECK-NEXT: ret i1 [[R]]16;17 %adjusted = add i8 %base, %offset18 call void @use8(i8 %adjusted)19 %not_null = icmp ne i8 %adjusted, 020 %no_underflow = icmp ule i8 %adjusted, %base21 %r = and i1 %not_null, %no_underflow22 ret i1 %r23}24 25define i1 @t0_logical(i8 %base, i8 %offset) {26; CHECK-LABEL: @t0_logical(27; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]28; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])29; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]30; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]31; CHECK-NEXT: ret i1 [[R]]32;33 %adjusted = add i8 %base, %offset34 call void @use8(i8 %adjusted)35 %not_null = icmp ne i8 %adjusted, 036 %no_underflow = icmp ule i8 %adjusted, %base37 %r = select i1 %not_null, i1 %no_underflow, i1 false38 ret i1 %r39}40 41; We need to produce extra instruction, so one of icmp's must go away.42define i1 @t1_oneuse0(i8 %base, i8 %offset) {43; CHECK-LABEL: @t1_oneuse0(44; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]45; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])46; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 047; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]])48; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]49; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]50; CHECK-NEXT: ret i1 [[R]]51;52 %adjusted = add i8 %base, %offset53 call void @use8(i8 %adjusted)54 %not_null = icmp ne i8 %adjusted, 055 call void @use1(i1 %not_null)56 %no_underflow = icmp ule i8 %adjusted, %base57 %r = and i1 %not_null, %no_underflow58 ret i1 %r59}60 61define i1 @t1_oneuse0_logical(i8 %base, i8 %offset) {62; CHECK-LABEL: @t1_oneuse0_logical(63; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]64; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])65; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 066; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]])67; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]68; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]69; CHECK-NEXT: ret i1 [[R]]70;71 %adjusted = add i8 %base, %offset72 call void @use8(i8 %adjusted)73 %not_null = icmp ne i8 %adjusted, 074 call void @use1(i1 %not_null)75 %no_underflow = icmp ule i8 %adjusted, %base76 %r = select i1 %not_null, i1 %no_underflow, i1 false77 ret i1 %r78}79define i1 @t2_oneuse1(i8 %base, i8 %offset) {80; CHECK-LABEL: @t2_oneuse1(81; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]82; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])83; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]84; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]])85; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]86; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]87; CHECK-NEXT: ret i1 [[R]]88;89 %adjusted = add i8 %base, %offset90 call void @use8(i8 %adjusted)91 %not_null = icmp ne i8 %adjusted, 092 %no_underflow = icmp ule i8 %adjusted, %base93 call void @use1(i1 %no_underflow)94 %r = and i1 %not_null, %no_underflow95 ret i1 %r96}97 98define i1 @t2_oneuse1_logical(i8 %base, i8 %offset) {99; CHECK-LABEL: @t2_oneuse1_logical(100; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]101; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])102; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]103; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]])104; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]105; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]106; CHECK-NEXT: ret i1 [[R]]107;108 %adjusted = add i8 %base, %offset109 call void @use8(i8 %adjusted)110 %not_null = icmp ne i8 %adjusted, 0111 %no_underflow = icmp ule i8 %adjusted, %base112 call void @use1(i1 %no_underflow)113 %r = select i1 %not_null, i1 %no_underflow, i1 false114 ret i1 %r115}116define i1 @n3_oneuse2_bad(i8 %base, i8 %offset) {117; CHECK-LABEL: @n3_oneuse2_bad(118; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]119; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])120; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0121; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]])122; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]123; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]])124; CHECK-NEXT: [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]125; CHECK-NEXT: ret i1 [[R]]126;127 %adjusted = add i8 %base, %offset128 call void @use8(i8 %adjusted)129 %not_null = icmp ne i8 %adjusted, 0130 call void @use1(i1 %not_null)131 %no_underflow = icmp ule i8 %adjusted, %base132 call void @use1(i1 %no_underflow)133 %r = and i1 %not_null, %no_underflow134 ret i1 %r135}136 137define i1 @n3_oneuse2_bad_logical(i8 %base, i8 %offset) {138; CHECK-LABEL: @n3_oneuse2_bad_logical(139; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]140; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])141; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0142; CHECK-NEXT: call void @use1(i1 [[NOT_NULL]])143; CHECK-NEXT: [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]144; CHECK-NEXT: call void @use1(i1 [[NO_UNDERFLOW]])145; CHECK-NEXT: [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]146; CHECK-NEXT: ret i1 [[R]]147;148 %adjusted = add i8 %base, %offset149 call void @use8(i8 %adjusted)150 %not_null = icmp ne i8 %adjusted, 0151 call void @use1(i1 %not_null)152 %no_underflow = icmp ule i8 %adjusted, %base153 call void @use1(i1 %no_underflow)154 %r = select i1 %not_null, i1 %no_underflow, i1 false155 ret i1 %r156}157 158define i1 @t4_commutativity0(i8 %base, i8 %offset) {159; CHECK-LABEL: @t4_commutativity0(160; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]161; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])162; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]163; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]164; CHECK-NEXT: ret i1 [[R]]165;166 %adjusted = add i8 %base, %offset167 call void @use8(i8 %adjusted)168 %not_null = icmp ne i8 %adjusted, 0169 %no_underflow = icmp ule i8 %adjusted, %base170 %r = and i1 %no_underflow, %not_null ; swapped171 ret i1 %r172}173 174define i1 @t4_commutativity0_logical(i8 %base, i8 %offset) {175; CHECK-LABEL: @t4_commutativity0_logical(176; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]177; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])178; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]179; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]180; CHECK-NEXT: ret i1 [[R]]181;182 %adjusted = add i8 %base, %offset183 call void @use8(i8 %adjusted)184 %not_null = icmp ne i8 %adjusted, 0185 %no_underflow = icmp ule i8 %adjusted, %base186 %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped187 ret i1 %r188}189define i1 @t5_commutativity1(i8 %base, i8 %offset) {190; CHECK-LABEL: @t5_commutativity1(191; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]192; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])193; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]194; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]195; CHECK-NEXT: ret i1 [[R]]196;197 %adjusted = add i8 %base, %offset198 call void @use8(i8 %adjusted)199 %not_null = icmp ne i8 %adjusted, 0200 %no_underflow = icmp uge i8 %base, %adjusted ; swapped201 %r = and i1 %not_null, %no_underflow202 ret i1 %r203}204 205define i1 @t5_commutativity1_logical(i8 %base, i8 %offset) {206; CHECK-LABEL: @t5_commutativity1_logical(207; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]208; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])209; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]210; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]211; CHECK-NEXT: ret i1 [[R]]212;213 %adjusted = add i8 %base, %offset214 call void @use8(i8 %adjusted)215 %not_null = icmp ne i8 %adjusted, 0216 %no_underflow = icmp uge i8 %base, %adjusted ; swapped217 %r = select i1 %not_null, i1 %no_underflow, i1 false218 ret i1 %r219}220define i1 @t6_commutativity3(i8 %base, i8 %offset) {221; CHECK-LABEL: @t6_commutativity3(222; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]223; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])224; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]225; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]226; CHECK-NEXT: ret i1 [[R]]227;228 %adjusted = add i8 %base, %offset229 call void @use8(i8 %adjusted)230 %not_null = icmp ne i8 %adjusted, 0231 %no_underflow = icmp uge i8 %base, %adjusted ; swapped232 %r = and i1 %no_underflow, %not_null ; swapped233 ret i1 %r234}235 236define i1 @t6_commutativity3_logical(i8 %base, i8 %offset) {237; CHECK-LABEL: @t6_commutativity3_logical(238; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]239; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])240; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]241; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[BASE]], [[TMP1]]242; CHECK-NEXT: ret i1 [[R]]243;244 %adjusted = add i8 %base, %offset245 call void @use8(i8 %adjusted)246 %not_null = icmp ne i8 %adjusted, 0247 %no_underflow = icmp uge i8 %base, %adjusted ; swapped248 %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped249 ret i1 %r250}251 252; We could have the opposite question, did we get null or overflow happened?253define i1 @t7(i8 %base, i8 %offset) {254; CHECK-LABEL: @t7(255; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]256; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])257; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]258; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[BASE]], [[TMP1]]259; CHECK-NEXT: ret i1 [[R]]260;261 %adjusted = add i8 %base, %offset262 call void @use8(i8 %adjusted)263 %not_null = icmp eq i8 %adjusted, 0264 %no_underflow = icmp ugt i8 %adjusted, %base265 %r = or i1 %not_null, %no_underflow266 ret i1 %r267}268 269define i1 @t7_logical(i8 %base, i8 %offset) {270; CHECK-LABEL: @t7_logical(271; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]272; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])273; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[OFFSET]]274; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[BASE]], [[TMP1]]275; CHECK-NEXT: ret i1 [[R]]276;277 %adjusted = add i8 %base, %offset278 call void @use8(i8 %adjusted)279 %not_null = icmp eq i8 %adjusted, 0280 %no_underflow = icmp ugt i8 %adjusted, %base281 %r = select i1 %not_null, i1 true, i1 %no_underflow282 ret i1 %r283}284 285; The comparison can be with any of the values being added.286define i1 @t8(i8 %base, i8 %offset) {287; CHECK-LABEL: @t8(288; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]289; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])290; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[BASE]]291; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[OFFSET]], [[TMP1]]292; CHECK-NEXT: ret i1 [[R]]293;294 %adjusted = add i8 %base, %offset295 call void @use8(i8 %adjusted)296 %not_null = icmp ne i8 %adjusted, 0297 %no_underflow = icmp ule i8 %adjusted, %offset298 %r = and i1 %not_null, %no_underflow299 ret i1 %r300}301 302define i1 @t8_logical(i8 %base, i8 %offset) {303; CHECK-LABEL: @t8_logical(304; CHECK-NEXT: [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]305; CHECK-NEXT: call void @use8(i8 [[ADJUSTED]])306; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[BASE]]307; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[OFFSET]], [[TMP1]]308; CHECK-NEXT: ret i1 [[R]]309;310 %adjusted = add i8 %base, %offset311 call void @use8(i8 %adjusted)312 %not_null = icmp ne i8 %adjusted, 0313 %no_underflow = icmp ule i8 %adjusted, %offset314 %r = select i1 %not_null, i1 %no_underflow, i1 false315 ret i1 %r316}317