1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4; In the next 16 tests (4 commutes * 2 (and/or) * 2 optional ptrtoint casts), 5; eliminate the simple (not) null check because that compare is implied by the 6; masked compare of the same operand. 7; Vary types between scalar and vector and weird for extra coverage. 8 9; or (icmp eq (and X, ?), 0), (icmp eq X, 0) --> icmp eq (and X, ?), 0 10 11define i1 @or_cmps_eq_zero_with_mask_commute1(i64 %x, i64 %y) { 12; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute1( 13; CHECK-NEXT: [[SOMEBITS:%.*]] = and i64 [[X:%.*]], [[Y:%.*]] 14; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i64 [[SOMEBITS]], 0 15; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_ZERO]] 16; 17 %isnull = icmp eq i64 %x, 0 18 %somebits = and i64 %x, %y 19 %somebits_are_zero = icmp eq i64 %somebits, 0 20 %r = or i1 %somebits_are_zero, %isnull 21 ret i1 %r 22} 23 24; or (icmp eq X, 0), (icmp eq (and X, ?), 0) --> icmp eq (and X, ?), 0 25 26define <2 x i1> @or_cmps_eq_zero_with_mask_commute2(<2 x i64> %x, <2 x i64> %y) { 27; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute2( 28; CHECK-NEXT: [[SOMEBITS:%.*]] = and <2 x i64> [[X:%.*]], [[Y:%.*]] 29; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i64> [[SOMEBITS]], zeroinitializer 30; CHECK-NEXT: ret <2 x i1> [[SOMEBITS_ARE_ZERO]] 31; 32 %isnull = icmp eq <2 x i64> %x, zeroinitializer 33 %somebits = and <2 x i64> %x, %y 34 %somebits_are_zero = icmp eq <2 x i64> %somebits, zeroinitializer 35 %r = or <2 x i1> %isnull, %somebits_are_zero 36 ret <2 x i1> %r 37} 38 39; or (icmp eq (and ?, X), 0), (icmp eq X, 0) --> icmp eq (and ?, X), 0 40 41define i1 @or_cmps_eq_zero_with_mask_commute3(i4 %x, i4 %y) { 42; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute3( 43; CHECK-NEXT: [[SOMEBITS:%.*]] = and i4 [[Y:%.*]], [[X:%.*]] 44; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i4 [[SOMEBITS]], 0 45; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_ZERO]] 46; 47 %isnull = icmp eq i4 %x, 0 48 %somebits = and i4 %y, %x 49 %somebits_are_zero = icmp eq i4 %somebits, 0 50 %r = or i1 %somebits_are_zero, %isnull 51 ret i1 %r 52} 53 54; or (icmp eq X, 0), (icmp eq (and ?, X), 0) --> icmp eq (and ?, X), 0 55 56define <2 x i1> @or_cmps_eq_zero_with_mask_commute4(<2 x i4> %x, <2 x i4> %y) { 57; CHECK-LABEL: @or_cmps_eq_zero_with_mask_commute4( 58; CHECK-NEXT: [[SOMEBITS:%.*]] = and <2 x i4> [[Y:%.*]], [[X:%.*]] 59; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[SOMEBITS]], zeroinitializer 60; CHECK-NEXT: ret <2 x i1> [[SOMEBITS_ARE_ZERO]] 61; 62 %isnull = icmp eq <2 x i4> %x, zeroinitializer 63 %somebits = and <2 x i4> %y, %x 64 %somebits_are_zero = icmp eq <2 x i4> %somebits, zeroinitializer 65 %r = or <2 x i1> %isnull, %somebits_are_zero 66 ret <2 x i1> %r 67} 68 69; and (icmp ne (and X, ?), 0), (icmp ne X, 0) --> icmp ne (and X, ?), 0 70 71define <3 x i1> @and_cmps_eq_zero_with_mask_commute1(<3 x i4> %x, <3 x i4> %y) { 72; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute1( 73; CHECK-NEXT: [[SOMEBITS:%.*]] = and <3 x i4> [[X:%.*]], [[Y:%.*]] 74; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i4> [[SOMEBITS]], zeroinitializer 75; CHECK-NEXT: ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]] 76; 77 %isnotnull = icmp ne <3 x i4> %x, zeroinitializer 78 %somebits = and <3 x i4> %x, %y 79 %somebits_are_not_zero = icmp ne <3 x i4> %somebits, zeroinitializer 80 %r = and <3 x i1> %somebits_are_not_zero, %isnotnull 81 ret <3 x i1> %r 82} 83 84; and (icmp ne X, 0), (icmp ne (and X, ?), 0) --> icmp ne (and X, ?), 0 85 86define i1 @and_cmps_eq_zero_with_mask_commute2(i4 %x, i4 %y) { 87; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute2( 88; CHECK-NEXT: [[SOMEBITS:%.*]] = and i4 [[X:%.*]], [[Y:%.*]] 89; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i4 [[SOMEBITS]], 0 90; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_NOT_ZERO]] 91; 92 %isnotnull = icmp ne i4 %x, 0 93 %somebits = and i4 %x, %y 94 %somebits_are_not_zero = icmp ne i4 %somebits, 0 95 %r = and i1 %isnotnull, %somebits_are_not_zero 96 ret i1 %r 97} 98 99; and (icmp ne (and ?, X), 0), (icmp ne X, 0) --> icmp ne (and ?, X), 0 100 101define <3 x i1> @and_cmps_eq_zero_with_mask_commute3(<3 x i64> %x, <3 x i64> %y) { 102; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute3( 103; CHECK-NEXT: [[SOMEBITS:%.*]] = and <3 x i64> [[Y:%.*]], [[X:%.*]] 104; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i64> [[SOMEBITS]], zeroinitializer 105; CHECK-NEXT: ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]] 106; 107 %isnotnull = icmp ne <3 x i64> %x, zeroinitializer 108 %somebits = and <3 x i64> %y, %x 109 %somebits_are_not_zero = icmp ne <3 x i64> %somebits, zeroinitializer 110 %r = and <3 x i1> %somebits_are_not_zero, %isnotnull 111 ret <3 x i1> %r 112} 113 114; and (icmp ne X, 0), (icmp ne (and ?, X), 0) --> icmp ne (and ?, X), 0 115 116define i1 @and_cmps_eq_zero_with_mask_commute4(i64 %x, i64 %y) { 117; CHECK-LABEL: @and_cmps_eq_zero_with_mask_commute4( 118; CHECK-NEXT: [[SOMEBITS:%.*]] = and i64 [[Y:%.*]], [[X:%.*]] 119; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i64 [[SOMEBITS]], 0 120; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_NOT_ZERO]] 121; 122 %isnotnull = icmp ne i64 %x, 0 123 %somebits = and i64 %y, %x 124 %somebits_are_not_zero = icmp ne i64 %somebits, 0 125 %r = and i1 %isnotnull, %somebits_are_not_zero 126 ret i1 %r 127} 128 129; or (icmp eq (and (ptrtoint P), ?), 0), (icmp eq P, 0) --> icmp eq (and (ptrtoint P), ?), 0 130 131define i1 @or_cmps_ptr_eq_zero_with_mask_commute1(ptr %p, i64 %y) { 132; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute1( 133; CHECK-NEXT: [[X:%.*]] = ptrtoint ptr [[P:%.*]] to i64 134; CHECK-NEXT: [[SOMEBITS:%.*]] = and i64 [[X]], [[Y:%.*]] 135; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i64 [[SOMEBITS]], 0 136; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_ZERO]] 137; 138 %isnull = icmp eq ptr %p, null 139 %x = ptrtoint ptr %p to i64 140 %somebits = and i64 %x, %y 141 %somebits_are_zero = icmp eq i64 %somebits, 0 142 %r = or i1 %somebits_are_zero, %isnull 143 ret i1 %r 144} 145 146; or (icmp eq P, 0), (icmp eq (and (ptrtoint P), ?), 0) --> icmp eq (and (ptrtoint P), ?), 0 147 148define <2 x i1> @or_cmps_ptr_eq_zero_with_mask_commute2(<2 x ptr> %p, <2 x i64> %y) { 149; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute2( 150; CHECK-NEXT: [[X:%.*]] = ptrtoint <2 x ptr> [[P:%.*]] to <2 x i64> 151; CHECK-NEXT: [[SOMEBITS:%.*]] = and <2 x i64> [[X]], [[Y:%.*]] 152; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i64> [[SOMEBITS]], zeroinitializer 153; CHECK-NEXT: ret <2 x i1> [[SOMEBITS_ARE_ZERO]] 154; 155 %isnull = icmp eq <2 x ptr> %p, zeroinitializer 156 %x = ptrtoint <2 x ptr> %p to <2 x i64> 157 %somebits = and <2 x i64> %x, %y 158 %somebits_are_zero = icmp eq <2 x i64> %somebits, zeroinitializer 159 %r = or <2 x i1> %isnull, %somebits_are_zero 160 ret <2 x i1> %r 161} 162 163; or (icmp eq (and ?, (ptrtoint P)), 0), (icmp eq P, 0) --> icmp eq (and ?, (ptrtoint P)), 0 164 165define i1 @or_cmps_ptr_eq_zero_with_mask_commute3(ptr %p, i4 %y) { 166; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute3( 167; CHECK-NEXT: [[X:%.*]] = ptrtoint ptr [[P:%.*]] to i4 168; CHECK-NEXT: [[SOMEBITS:%.*]] = and i4 [[Y:%.*]], [[X]] 169; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq i4 [[SOMEBITS]], 0 170; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_ZERO]] 171; 172 %isnull = icmp eq ptr %p, null 173 %x = ptrtoint ptr %p to i4 174 %somebits = and i4 %y, %x 175 %somebits_are_zero = icmp eq i4 %somebits, 0 176 %r = or i1 %somebits_are_zero, %isnull 177 ret i1 %r 178} 179 180; or (icmp eq P, 0), (icmp eq (and ?, (ptrtoint P)), 0) --> icmp eq (and ?, (ptrtoint P)), 0 181 182define <2 x i1> @or_cmps_ptr_eq_zero_with_mask_commute4(<2 x ptr> %p, <2 x i4> %y) { 183; CHECK-LABEL: @or_cmps_ptr_eq_zero_with_mask_commute4( 184; CHECK-NEXT: [[X:%.*]] = ptrtoint <2 x ptr> [[P:%.*]] to <2 x i4> 185; CHECK-NEXT: [[SOMEBITS:%.*]] = and <2 x i4> [[Y:%.*]], [[X]] 186; CHECK-NEXT: [[SOMEBITS_ARE_ZERO:%.*]] = icmp eq <2 x i4> [[SOMEBITS]], zeroinitializer 187; CHECK-NEXT: ret <2 x i1> [[SOMEBITS_ARE_ZERO]] 188; 189 %isnull = icmp eq <2 x ptr> %p, zeroinitializer 190 %x = ptrtoint <2 x ptr> %p to <2 x i4> 191 %somebits = and <2 x i4> %y, %x 192 %somebits_are_zero = icmp eq <2 x i4> %somebits, zeroinitializer 193 %r = or <2 x i1> %isnull, %somebits_are_zero 194 ret <2 x i1> %r 195} 196 197; and (icmp ne (and (ptrtoint P), ?), 0), (icmp ne P, 0) --> icmp ne (and (ptrtoint P), ?), 0 198 199define <3 x i1> @and_cmps_ptr_eq_zero_with_mask_commute1(<3 x ptr> %p, <3 x i4> %y) { 200; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute1( 201; CHECK-NEXT: [[X:%.*]] = ptrtoint <3 x ptr> [[P:%.*]] to <3 x i4> 202; CHECK-NEXT: [[SOMEBITS:%.*]] = and <3 x i4> [[X]], [[Y:%.*]] 203; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i4> [[SOMEBITS]], zeroinitializer 204; CHECK-NEXT: ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]] 205; 206 %isnotnull = icmp ne <3 x ptr> %p, zeroinitializer 207 %x = ptrtoint <3 x ptr> %p to <3 x i4> 208 %somebits = and <3 x i4> %x, %y 209 %somebits_are_not_zero = icmp ne <3 x i4> %somebits, zeroinitializer 210 %r = and <3 x i1> %somebits_are_not_zero, %isnotnull 211 ret <3 x i1> %r 212} 213 214; and (icmp ne P, 0), (icmp ne (and (ptrtoint P), ?), 0) --> icmp ne (and (ptrtoint P), ?), 0 215 216define i1 @and_cmps_ptr_eq_zero_with_mask_commute2(ptr %p, i4 %y) { 217; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute2( 218; CHECK-NEXT: [[X:%.*]] = ptrtoint ptr [[P:%.*]] to i4 219; CHECK-NEXT: [[SOMEBITS:%.*]] = and i4 [[X]], [[Y:%.*]] 220; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i4 [[SOMEBITS]], 0 221; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_NOT_ZERO]] 222; 223 %isnotnull = icmp ne ptr %p, null 224 %x = ptrtoint ptr %p to i4 225 %somebits = and i4 %x, %y 226 %somebits_are_not_zero = icmp ne i4 %somebits, 0 227 %r = and i1 %isnotnull, %somebits_are_not_zero 228 ret i1 %r 229} 230 231; and (icmp ne (and ?, (ptrtoint P)), 0), (icmp ne P, 0) --> icmp ne (and ?, (ptrtoint P)), 0 232 233define <3 x i1> @and_cmps_ptr_eq_zero_with_mask_commute3(<3 x ptr> %p, <3 x i64> %y) { 234; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute3( 235; CHECK-NEXT: [[X:%.*]] = ptrtoint <3 x ptr> [[P:%.*]] to <3 x i64> 236; CHECK-NEXT: [[SOMEBITS:%.*]] = and <3 x i64> [[Y:%.*]], [[X]] 237; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne <3 x i64> [[SOMEBITS]], zeroinitializer 238; CHECK-NEXT: ret <3 x i1> [[SOMEBITS_ARE_NOT_ZERO]] 239; 240 %isnotnull = icmp ne <3 x ptr> %p, zeroinitializer 241 %x = ptrtoint <3 x ptr> %p to <3 x i64> 242 %somebits = and <3 x i64> %y, %x 243 %somebits_are_not_zero = icmp ne <3 x i64> %somebits, zeroinitializer 244 %r = and <3 x i1> %somebits_are_not_zero, %isnotnull 245 ret <3 x i1> %r 246} 247 248; and (icmp ne P, 0), (icmp ne (and ?, (ptrtoint P)), 0) --> icmp ne (and ?, (ptrtoint P)), 0 249 250define i1 @and_cmps_ptr_eq_zero_with_mask_commute4(ptr %p, i64 %y) { 251; CHECK-LABEL: @and_cmps_ptr_eq_zero_with_mask_commute4( 252; CHECK-NEXT: [[X:%.*]] = ptrtoint ptr [[P:%.*]] to i64 253; CHECK-NEXT: [[SOMEBITS:%.*]] = and i64 [[Y:%.*]], [[X]] 254; CHECK-NEXT: [[SOMEBITS_ARE_NOT_ZERO:%.*]] = icmp ne i64 [[SOMEBITS]], 0 255; CHECK-NEXT: ret i1 [[SOMEBITS_ARE_NOT_ZERO]] 256; 257 %isnotnull = icmp ne ptr %p, null 258 %x = ptrtoint ptr %p to i64 259 %somebits = and i64 %y, %x 260 %somebits_are_not_zero = icmp ne i64 %somebits, 0 261 %r = and i1 %isnotnull, %somebits_are_not_zero 262 ret i1 %r 263} 264