1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; This test case tests the InstructionCombining optimization that 3; reduces things like: 4; %Y = sext i8 %X to i32 5; %C = icmp ult i32 %Y, 1024 6; to 7; %C = i1 true 8; It includes test cases for different constant values, signedness of the 9; cast operands, and types of setCC operators. In all cases, the cast should 10; be eliminated. In many cases the setCC is also eliminated based on the 11; constant value and the range of the casted value. 12; 13; RUN: opt < %s -instcombine -S | FileCheck %s 14 15define i1 @lt_signed_to_large_unsigned(i8 %SB) { 16; CHECK-LABEL: @lt_signed_to_large_unsigned( 17; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 %SB, -1 18; CHECK-NEXT: ret i1 [[C1]] 19; 20 %Y = sext i8 %SB to i32 21 %C = icmp ult i32 %Y, 1024 22 ret i1 %C 23} 24 25; PR28011 - https://llvm.org/bugs/show_bug.cgi?id=28011 26; The above transform only applies to scalar integers; it shouldn't be attempted for constant expressions or vectors. 27 28@a = common global i32** null 29@b = common global [1 x i32] zeroinitializer 30 31define i1 @PR28011(i16 %a) { 32; CHECK-LABEL: @PR28011( 33; CHECK-NEXT: [[CONV:%.*]] = sext i16 %a to i32 34; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CONV]], or (i32 zext (i1 icmp ne (i32*** bitcast ([1 x i32]* @b to i32***), i32*** @a) to i32), i32 1) 35; CHECK-NEXT: ret i1 [[CMP]] 36; 37 %conv = sext i16 %a to i32 38 %cmp = icmp ne i32 %conv, or (i32 zext (i1 icmp ne (i32*** bitcast ([1 x i32]* @b to i32***), i32*** @a) to i32), i32 1) 39 ret i1 %cmp 40} 41 42define <2 x i1> @lt_signed_to_large_unsigned_vec(<2 x i8> %SB) { 43; CHECK-LABEL: @lt_signed_to_large_unsigned_vec( 44; CHECK-NEXT: [[Y:%.*]] = sext <2 x i8> %SB to <2 x i32> 45; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> [[Y]], <i32 1024, i32 2> 46; CHECK-NEXT: ret <2 x i1> [[C]] 47; 48 %Y = sext <2 x i8> %SB to <2 x i32> 49 %C = icmp ult <2 x i32> %Y, <i32 1024, i32 2> 50 ret <2 x i1> %C 51} 52 53define i1 @lt_signed_to_large_signed(i8 %SB) { 54; CHECK-LABEL: @lt_signed_to_large_signed( 55; CHECK-NEXT: ret i1 true 56; 57 %Y = sext i8 %SB to i32 58 %C = icmp slt i32 %Y, 1024 59 ret i1 %C 60} 61 62define i1 @lt_signed_to_large_negative(i8 %SB) { 63; CHECK-LABEL: @lt_signed_to_large_negative( 64; CHECK-NEXT: ret i1 false 65; 66 %Y = sext i8 %SB to i32 67 %C = icmp slt i32 %Y, -1024 68 ret i1 %C 69} 70 71define i1 @lt_signed_to_small_unsigned(i8 %SB) { 72; CHECK-LABEL: @lt_signed_to_small_unsigned( 73; CHECK-NEXT: [[C:%.*]] = icmp ult i8 %SB, 17 74; CHECK-NEXT: ret i1 [[C]] 75; 76 %Y = sext i8 %SB to i32 77 %C = icmp ult i32 %Y, 17 78 ret i1 %C 79} 80 81define i1 @lt_signed_to_small_signed(i8 %SB) { 82; CHECK-LABEL: @lt_signed_to_small_signed( 83; CHECK-NEXT: [[C:%.*]] = icmp slt i8 %SB, 17 84; CHECK-NEXT: ret i1 [[C]] 85; 86 %Y = sext i8 %SB to i32 87 %C = icmp slt i32 %Y, 17 88 ret i1 %C 89} 90define i1 @lt_signed_to_small_negative(i8 %SB) { 91; CHECK-LABEL: @lt_signed_to_small_negative( 92; CHECK-NEXT: [[C:%.*]] = icmp slt i8 %SB, -17 93; CHECK-NEXT: ret i1 [[C]] 94; 95 %Y = sext i8 %SB to i32 96 %C = icmp slt i32 %Y, -17 97 ret i1 %C 98} 99 100define i1 @lt_unsigned_to_large_unsigned(i8 %SB) { 101; CHECK-LABEL: @lt_unsigned_to_large_unsigned( 102; CHECK-NEXT: ret i1 true 103; 104 %Y = zext i8 %SB to i32 105 %C = icmp ult i32 %Y, 1024 106 ret i1 %C 107} 108 109define i1 @lt_unsigned_to_large_signed(i8 %SB) { 110; CHECK-LABEL: @lt_unsigned_to_large_signed( 111; CHECK-NEXT: ret i1 true 112; 113 %Y = zext i8 %SB to i32 114 %C = icmp slt i32 %Y, 1024 115 ret i1 %C 116} 117 118define i1 @lt_unsigned_to_large_negative(i8 %SB) { 119; CHECK-LABEL: @lt_unsigned_to_large_negative( 120; CHECK-NEXT: ret i1 false 121; 122 %Y = zext i8 %SB to i32 123 %C = icmp slt i32 %Y, -1024 124 ret i1 %C 125} 126 127define i1 @lt_unsigned_to_small_unsigned(i8 %SB) { 128; CHECK-LABEL: @lt_unsigned_to_small_unsigned( 129; CHECK-NEXT: [[C:%.*]] = icmp ult i8 %SB, 17 130; CHECK-NEXT: ret i1 [[C]] 131; 132 %Y = zext i8 %SB to i32 133 %C = icmp ult i32 %Y, 17 134 ret i1 %C 135} 136 137define i1 @lt_unsigned_to_small_signed(i8 %SB) { 138; CHECK-LABEL: @lt_unsigned_to_small_signed( 139; CHECK-NEXT: [[C:%.*]] = icmp ult i8 %SB, 17 140; CHECK-NEXT: ret i1 [[C]] 141; 142 %Y = zext i8 %SB to i32 143 %C = icmp slt i32 %Y, 17 144 ret i1 %C 145} 146 147define i1 @lt_unsigned_to_small_negative(i8 %SB) { 148; CHECK-LABEL: @lt_unsigned_to_small_negative( 149; CHECK-NEXT: ret i1 false 150; 151 %Y = zext i8 %SB to i32 152 %C = icmp slt i32 %Y, -17 153 ret i1 %C 154} 155 156define i1 @gt_signed_to_large_unsigned(i8 %SB) { 157; CHECK-LABEL: @gt_signed_to_large_unsigned( 158; CHECK-NEXT: [[C:%.*]] = icmp slt i8 %SB, 0 159; CHECK-NEXT: ret i1 [[C]] 160; 161 %Y = sext i8 %SB to i32 162 %C = icmp ugt i32 %Y, 1024 163 ret i1 %C 164} 165 166define i1 @gt_signed_to_large_signed(i8 %SB) { 167; CHECK-LABEL: @gt_signed_to_large_signed( 168; CHECK-NEXT: ret i1 false 169; 170 %Y = sext i8 %SB to i32 171 %C = icmp sgt i32 %Y, 1024 172 ret i1 %C 173} 174 175define i1 @gt_signed_to_large_negative(i8 %SB) { 176; CHECK-LABEL: @gt_signed_to_large_negative( 177; CHECK-NEXT: ret i1 true 178; 179 %Y = sext i8 %SB to i32 180 %C = icmp sgt i32 %Y, -1024 181 ret i1 %C 182} 183 184define i1 @gt_signed_to_small_unsigned(i8 %SB) { 185; CHECK-LABEL: @gt_signed_to_small_unsigned( 186; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 %SB, 17 187; CHECK-NEXT: ret i1 [[C]] 188; 189 %Y = sext i8 %SB to i32 190 %C = icmp ugt i32 %Y, 17 191 ret i1 %C 192} 193 194define i1 @gt_signed_to_small_signed(i8 %SB) { 195; CHECK-LABEL: @gt_signed_to_small_signed( 196; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 %SB, 17 197; CHECK-NEXT: ret i1 [[C]] 198; 199 %Y = sext i8 %SB to i32 200 %C = icmp sgt i32 %Y, 17 201 ret i1 %C 202} 203 204define i1 @gt_signed_to_small_negative(i8 %SB) { 205; CHECK-LABEL: @gt_signed_to_small_negative( 206; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 %SB, -17 207; CHECK-NEXT: ret i1 [[C]] 208; 209 %Y = sext i8 %SB to i32 210 %C = icmp sgt i32 %Y, -17 211 ret i1 %C 212} 213 214define i1 @gt_unsigned_to_large_unsigned(i8 %SB) { 215; CHECK-LABEL: @gt_unsigned_to_large_unsigned( 216; CHECK-NEXT: ret i1 false 217; 218 %Y = zext i8 %SB to i32 219 %C = icmp ugt i32 %Y, 1024 220 ret i1 %C 221} 222 223define i1 @gt_unsigned_to_large_signed(i8 %SB) { 224; CHECK-LABEL: @gt_unsigned_to_large_signed( 225; CHECK-NEXT: ret i1 false 226; 227 %Y = zext i8 %SB to i32 228 %C = icmp sgt i32 %Y, 1024 229 ret i1 %C 230} 231 232define i1 @gt_unsigned_to_large_negative(i8 %SB) { 233; CHECK-LABEL: @gt_unsigned_to_large_negative( 234; CHECK-NEXT: ret i1 true 235; 236 %Y = zext i8 %SB to i32 237 %C = icmp sgt i32 %Y, -1024 238 ret i1 %C 239} 240 241define i1 @gt_unsigned_to_small_unsigned(i8 %SB) { 242; CHECK-LABEL: @gt_unsigned_to_small_unsigned( 243; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 %SB, 17 244; CHECK-NEXT: ret i1 [[C]] 245; 246 %Y = zext i8 %SB to i32 247 %C = icmp ugt i32 %Y, 17 248 ret i1 %C 249} 250 251define i1 @gt_unsigned_to_small_signed(i8 %SB) { 252; CHECK-LABEL: @gt_unsigned_to_small_signed( 253; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 %SB, 17 254; CHECK-NEXT: ret i1 [[C]] 255; 256 %Y = zext i8 %SB to i32 257 %C = icmp sgt i32 %Y, 17 258 ret i1 %C 259} 260 261define i1 @gt_unsigned_to_small_negative(i8 %SB) { 262; CHECK-LABEL: @gt_unsigned_to_small_negative( 263; CHECK-NEXT: ret i1 true 264; 265 %Y = zext i8 %SB to i32 266 %C = icmp sgt i32 %Y, -17 267 ret i1 %C 268} 269 270