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 15 define 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 31 define 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 42 define <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 53 define 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 62 define 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 71 define 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 81 define 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 } 90 define 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 100 define 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 109 define 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 118 define 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 127 define 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 137 define 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 147 define 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 156 define 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 166 define 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 175 define 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 184 define 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 194 define 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 204 define 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 214 define 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 223 define 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 232 define 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 241 define 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 251 define 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 261 define 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