brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.3 KiB · e95955d Raw
715 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Given pattern:5;   icmp eq/ne (and ((x shift Q), (y oppositeshift K))), 06; we should move shifts to the same hand of 'and', i.e. e.g. rewrite as7;   icmp eq/ne (and (((x shift Q) shift K), y)), 08; We are only interested in opposite logical shifts here.9 10; Basic scalar test with constants11 12define i1 @t0_const_lshr_shl_ne(i32 %x, i32 %y) {13; CHECK-LABEL: @t0_const_lshr_shl_ne(14; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 215; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]16; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 017; CHECK-NEXT:    ret i1 [[T3]]18;19  %t0 = lshr i32 %x, 120  %t1 = shl i32 %y, 121  %t2 = and i32 %t1, %t022  %t3 = icmp ne i32 %t2, 023  ret i1 %t324}25define i1 @t1_const_shl_lshr_ne(i32 %x, i32 %y) {26; CHECK-LABEL: @t1_const_shl_lshr_ne(27; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 228; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]29; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 030; CHECK-NEXT:    ret i1 [[T3]]31;32  %t0 = shl i32 %x, 133  %t1 = lshr i32 %y, 134  %t2 = and i32 %t1, %t035  %t3 = icmp ne i32 %t2, 036  ret i1 %t337}38 39; We are ok with 'eq' predicate too.40define i1 @t2_const_lshr_shl_eq(i32 %x, i32 %y) {41; CHECK-LABEL: @t2_const_lshr_shl_eq(42; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 243; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]44; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[TMP2]], 045; CHECK-NEXT:    ret i1 [[T3]]46;47  %t0 = lshr i32 %x, 148  %t1 = shl i32 %y, 149  %t2 = and i32 %t1, %t050  %t3 = icmp eq i32 %t2, 051  ret i1 %t352}53 54; Basic scalar test with constants after folding55 56define i1 @t3_const_after_fold_lshr_shl_ne(i32 %x, i32 %y, i32 %len) {57; CHECK-LABEL: @t3_const_after_fold_lshr_shl_ne(58; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 3159; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]60; CHECK-NEXT:    [[T5:%.*]] = icmp ne i32 [[TMP2]], 061; CHECK-NEXT:    ret i1 [[T5]]62;63  %t0 = sub i32 32, %len64  %t1 = lshr i32 %x, %t065  %t2 = add i32 %len, -166  %t3 = shl i32 %y, %t267  %t4 = and i32 %t1, %t368  %t5 = icmp ne i32 %t4, 069  ret i1 %t570}71define i1 @t4_const_after_fold_lshr_shl_ne(i32 %x, i32 %y, i32 %len) {72; CHECK-LABEL: @t4_const_after_fold_lshr_shl_ne(73; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 3174; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]75; CHECK-NEXT:    [[T5:%.*]] = icmp ne i32 [[TMP2]], 076; CHECK-NEXT:    ret i1 [[T5]]77;78  %t0 = sub i32 32, %len79  %t1 = shl i32 %x, %t080  %t2 = add i32 %len, -181  %t3 = lshr i32 %y, %t282  %t4 = and i32 %t1, %t383  %t5 = icmp ne i32 %t4, 084  ret i1 %t585}86 87; Completely variable shift amounts88 89define i1 @t5_const_lshr_shl_ne(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {90; CHECK-LABEL: @t5_const_lshr_shl_ne(91; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]92; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]93; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]94; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 095; CHECK-NEXT:    ret i1 [[T3]]96;97  %t0 = lshr i32 %x, %shamt098  %t1 = shl i32 %y, %shamt199  %t2 = and i32 %t1, %t0100  %t3 = icmp ne i32 %t2, 0101  ret i1 %t3102}103define i1 @t6_const_shl_lshr_ne(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {104; CHECK-LABEL: @t6_const_shl_lshr_ne(105; CHECK-NEXT:    [[T0:%.*]] = shl i32 [[X:%.*]], [[SHAMT0:%.*]]106; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[Y:%.*]], [[SHAMT1:%.*]]107; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]108; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0109; CHECK-NEXT:    ret i1 [[T3]]110;111  %t0 = shl i32 %x, %shamt0112  %t1 = lshr i32 %y, %shamt1113  %t2 = and i32 %t1, %t0114  %t3 = icmp ne i32 %t2, 0115  ret i1 %t3116}117 118; Very basic vector tests119 120define <2 x i1> @t7_const_lshr_shl_ne_vec_splat(<2 x i32> %x, <2 x i32> %y) {121; CHECK-LABEL: @t7_const_lshr_shl_ne_vec_splat(122; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 2)123; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[Y:%.*]]124; CHECK-NEXT:    [[T3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer125; CHECK-NEXT:    ret <2 x i1> [[T3]]126;127  %t0 = lshr <2 x i32> %x, <i32 1, i32 1>128  %t1 = shl <2 x i32> %y, <i32 1, i32 1>129  %t2 = and <2 x i32> %t1, %t0130  %t3 = icmp ne <2 x i32> %t2, <i32 0, i32 0>131  ret <2 x i1> %t3132}133define <2 x i1> @t8_const_lshr_shl_ne_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {134; CHECK-LABEL: @t8_const_lshr_shl_ne_vec_nonsplat(135; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 4, i32 6>136; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[Y:%.*]]137; CHECK-NEXT:    [[T3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer138; CHECK-NEXT:    ret <2 x i1> [[T3]]139;140  %t0 = lshr <2 x i32> %x, <i32 1, i32 2>141  %t1 = shl <2 x i32> %y, <i32 3, i32 4>142  %t2 = and <2 x i32> %t1, %t0143  %t3 = icmp ne <2 x i32> %t2, <i32 0, i32 0>144  ret <2 x i1> %t3145}146define <3 x i1> @t9_const_lshr_shl_ne_vec_poison0(<3 x i32> %x, <3 x i32> %y) {147; CHECK-LABEL: @t9_const_lshr_shl_ne_vec_poison0(148; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>149; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]150; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer151; CHECK-NEXT:    ret <3 x i1> [[T3]]152;153  %t0 = lshr <3 x i32> %x, <i32 1, i32 poison, i32 1>154  %t1 = shl <3 x i32> %y, <i32 1, i32 1, i32 1>155  %t2 = and <3 x i32> %t1, %t0156  %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 0, i32 0>157  ret <3 x i1> %t3158}159define <3 x i1> @t10_const_lshr_shl_ne_vec_poison1(<3 x i32> %x, <3 x i32> %y) {160; CHECK-LABEL: @t10_const_lshr_shl_ne_vec_poison1(161; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>162; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]163; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer164; CHECK-NEXT:    ret <3 x i1> [[T3]]165;166  %t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>167  %t1 = shl <3 x i32> %y, <i32 1, i32 poison, i32 1>168  %t2 = and <3 x i32> %t1, %t0169  %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 0, i32 0>170  ret <3 x i1> %t3171}172define <3 x i1> @t11_const_lshr_shl_ne_vec_poison2(<3 x i32> %x, <3 x i32> %y) {173; CHECK-LABEL: @t11_const_lshr_shl_ne_vec_poison2(174; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], splat (i32 2)175; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]176; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer177; CHECK-NEXT:    ret <3 x i1> [[T3]]178;179  %t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>180  %t1 = shl <3 x i32> %y, <i32 1, i32 1, i32 1>181  %t2 = and <3 x i32> %t1, %t0182  %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 poison, i32 0>183  ret <3 x i1> %t3184}185define <3 x i1> @t12_const_lshr_shl_ne_vec_poison3(<3 x i32> %x, <3 x i32> %y) {186; CHECK-LABEL: @t12_const_lshr_shl_ne_vec_poison3(187; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>188; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]189; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer190; CHECK-NEXT:    ret <3 x i1> [[T3]]191;192  %t0 = lshr <3 x i32> %x, <i32 1, i32 poison, i32 1>193  %t1 = shl <3 x i32> %y, <i32 1, i32 poison, i32 1>194  %t2 = and <3 x i32> %t1, %t0195  %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 0, i32 0>196  ret <3 x i1> %t3197}198define <3 x i1> @t13_const_lshr_shl_ne_vec_poison4(<3 x i32> %x, <3 x i32> %y) {199; CHECK-LABEL: @t13_const_lshr_shl_ne_vec_poison4(200; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>201; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]202; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer203; CHECK-NEXT:    ret <3 x i1> [[T3]]204;205  %t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>206  %t1 = shl <3 x i32> %y, <i32 1, i32 poison, i32 1>207  %t2 = and <3 x i32> %t1, %t0208  %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 poison, i32 0>209  ret <3 x i1> %t3210}211define <3 x i1> @t14_const_lshr_shl_ne_vec_poison5(<3 x i32> %x, <3 x i32> %y) {212; CHECK-LABEL: @t14_const_lshr_shl_ne_vec_poison5(213; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>214; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]215; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer216; CHECK-NEXT:    ret <3 x i1> [[T3]]217;218  %t0 = lshr <3 x i32> %x, <i32 1, i32 poison, i32 1>219  %t1 = shl <3 x i32> %y, <i32 1, i32 1, i32 1>220  %t2 = and <3 x i32> %t1, %t0221  %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 poison, i32 0>222  ret <3 x i1> %t3223}224define <3 x i1> @t15_const_lshr_shl_ne_vec_poison6(<3 x i32> %x, <3 x i32> %y) {225; CHECK-LABEL: @t15_const_lshr_shl_ne_vec_poison6(226; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>227; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]228; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer229; CHECK-NEXT:    ret <3 x i1> [[T3]]230;231  %t0 = lshr <3 x i32> %x, <i32 1, i32 poison, i32 1>232  %t1 = shl <3 x i32> %y, <i32 1, i32 poison, i32 1>233  %t2 = and <3 x i32> %t1, %t0234  %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 poison, i32 0>235  ret <3 x i1> %t3236}237 238; Commutativity tests239 240declare i32 @gen32()241 242define i1 @t16_commutativity0(i32 %x) {243; CHECK-LABEL: @t16_commutativity0(244; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()245; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2246; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]247; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0248; CHECK-NEXT:    ret i1 [[T3]]249;250  %y = call i32 @gen32()251  %t0 = lshr i32 %x, 1252  %t1 = shl i32 %y, 1253  %t2 = and i32 %t1, %t0254  %t3 = icmp ne i32 %t2, 0255  ret i1 %t3256}257 258define i1 @t17_commutativity1(i32 %y) {259; CHECK-LABEL: @t17_commutativity1(260; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()261; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2262; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]263; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0264; CHECK-NEXT:    ret i1 [[T3]]265;266  %x = call i32 @gen32()267  %t0 = lshr i32 %x, 1268  %t1 = shl i32 %y, 1269  %t2 = and i32 %t0, %t1 ; "swapped"270  %t3 = icmp ne i32 %t2, 0271  ret i1 %t3272}273 274; One-use tests275 276declare void @use32(i32)277 278define i1 @t18_const_oneuse0(i32 %x, i32 %y) {279; CHECK-LABEL: @t18_const_oneuse0(280; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1281; CHECK-NEXT:    call void @use32(i32 [[T0]])282; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2283; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]284; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0285; CHECK-NEXT:    ret i1 [[T3]]286;287  %t0 = lshr i32 %x, 1288  call void @use32(i32 %t0)289  %t1 = shl i32 %y, 1290  %t2 = and i32 %t1, %t0291  %t3 = icmp ne i32 %t2, 0292  ret i1 %t3293}294define i1 @t19_const_oneuse1(i32 %x, i32 %y) {295; CHECK-LABEL: @t19_const_oneuse1(296; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1297; CHECK-NEXT:    call void @use32(i32 [[T1]])298; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2299; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]300; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0301; CHECK-NEXT:    ret i1 [[T3]]302;303  %t0 = lshr i32 %x, 1304  %t1 = shl i32 %y, 1305  call void @use32(i32 %t1)306  %t2 = and i32 %t1, %t0307  %t3 = icmp ne i32 %t2, 0308  ret i1 %t3309}310define i1 @t20_const_oneuse2(i32 %x, i32 %y) {311; CHECK-LABEL: @t20_const_oneuse2(312; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1313; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1314; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]315; CHECK-NEXT:    call void @use32(i32 [[T2]])316; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0317; CHECK-NEXT:    ret i1 [[T3]]318;319  %t0 = lshr i32 %x, 1320  %t1 = shl i32 %y, 1321  %t2 = and i32 %t1, %t0322  call void @use32(i32 %t2)323  %t3 = icmp ne i32 %t2, 0324  ret i1 %t3325}326define i1 @t21_const_oneuse3(i32 %x, i32 %y) {327; CHECK-LABEL: @t21_const_oneuse3(328; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1329; CHECK-NEXT:    call void @use32(i32 [[T0]])330; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1331; CHECK-NEXT:    call void @use32(i32 [[T1]])332; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]333; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0334; CHECK-NEXT:    ret i1 [[T3]]335;336  %t0 = lshr i32 %x, 1337  call void @use32(i32 %t0)338  %t1 = shl i32 %y, 1339  call void @use32(i32 %t1)340  %t2 = and i32 %t1, %t0341  %t3 = icmp ne i32 %t2, 0342  ret i1 %t3343}344define i1 @t22_const_oneuse4(i32 %x, i32 %y) {345; CHECK-LABEL: @t22_const_oneuse4(346; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1347; CHECK-NEXT:    call void @use32(i32 [[T0]])348; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1349; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]350; CHECK-NEXT:    call void @use32(i32 [[T2]])351; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0352; CHECK-NEXT:    ret i1 [[T3]]353;354  %t0 = lshr i32 %x, 1355  call void @use32(i32 %t0)356  %t1 = shl i32 %y, 1357  %t2 = and i32 %t1, %t0358  call void @use32(i32 %t2)359  %t3 = icmp ne i32 %t2, 0360  ret i1 %t3361}362define i1 @t23_const_oneuse5(i32 %x, i32 %y) {363; CHECK-LABEL: @t23_const_oneuse5(364; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1365; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1366; CHECK-NEXT:    call void @use32(i32 [[T1]])367; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]368; CHECK-NEXT:    call void @use32(i32 [[T2]])369; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0370; CHECK-NEXT:    ret i1 [[T3]]371;372  %t0 = lshr i32 %x, 1373  %t1 = shl i32 %y, 1374  call void @use32(i32 %t1)375  %t2 = and i32 %t1, %t0376  call void @use32(i32 %t2)377  %t3 = icmp ne i32 %t2, 0378  ret i1 %t3379}380define i1 @t24_const_oneuse6(i32 %x, i32 %y) {381; CHECK-LABEL: @t24_const_oneuse6(382; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1383; CHECK-NEXT:    call void @use32(i32 [[T0]])384; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1385; CHECK-NEXT:    call void @use32(i32 [[T1]])386; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]387; CHECK-NEXT:    call void @use32(i32 [[T2]])388; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0389; CHECK-NEXT:    ret i1 [[T3]]390;391  %t0 = lshr i32 %x, 1392  call void @use32(i32 %t0)393  %t1 = shl i32 %y, 1394  call void @use32(i32 %t1)395  %t2 = and i32 %t1, %t0396  call void @use32(i32 %t2)397  %t3 = icmp ne i32 %t2, 0398  ret i1 %t3399}400 401define i1 @t25_var_oneuse0(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {402; CHECK-LABEL: @t25_var_oneuse0(403; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]404; CHECK-NEXT:    call void @use32(i32 [[T0]])405; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]406; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]407; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0408; CHECK-NEXT:    ret i1 [[T3]]409;410  %t0 = lshr i32 %x, %shamt0411  call void @use32(i32 %t0)412  %t1 = shl i32 %y, %shamt1413  %t2 = and i32 %t1, %t0414  %t3 = icmp ne i32 %t2, 0415  ret i1 %t3416}417define i1 @t26_var_oneuse1(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {418; CHECK-LABEL: @t26_var_oneuse1(419; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]420; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]421; CHECK-NEXT:    call void @use32(i32 [[T1]])422; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]423; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0424; CHECK-NEXT:    ret i1 [[T3]]425;426  %t0 = lshr i32 %x, %shamt0427  %t1 = shl i32 %y, %shamt1428  call void @use32(i32 %t1)429  %t2 = and i32 %t1, %t0430  %t3 = icmp ne i32 %t2, 0431  ret i1 %t3432}433define i1 @t27_var_oneuse2(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {434; CHECK-LABEL: @t27_var_oneuse2(435; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]436; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]437; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]438; CHECK-NEXT:    call void @use32(i32 [[T2]])439; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0440; CHECK-NEXT:    ret i1 [[T3]]441;442  %t0 = lshr i32 %x, %shamt0443  %t1 = shl i32 %y, %shamt1444  %t2 = and i32 %t1, %t0445  call void @use32(i32 %t2)446  %t3 = icmp ne i32 %t2, 0447  ret i1 %t3448}449define i1 @t28_var_oneuse3(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {450; CHECK-LABEL: @t28_var_oneuse3(451; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]452; CHECK-NEXT:    call void @use32(i32 [[T0]])453; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]454; CHECK-NEXT:    call void @use32(i32 [[T1]])455; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]456; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0457; CHECK-NEXT:    ret i1 [[T3]]458;459  %t0 = lshr i32 %x, %shamt0460  call void @use32(i32 %t0)461  %t1 = shl i32 %y, %shamt1462  call void @use32(i32 %t1)463  %t2 = and i32 %t1, %t0464  %t3 = icmp ne i32 %t2, 0465  ret i1 %t3466}467define i1 @t29_var_oneuse4(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {468; CHECK-LABEL: @t29_var_oneuse4(469; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]470; CHECK-NEXT:    call void @use32(i32 [[T0]])471; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]472; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]473; CHECK-NEXT:    call void @use32(i32 [[T2]])474; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0475; CHECK-NEXT:    ret i1 [[T3]]476;477  %t0 = lshr i32 %x, %shamt0478  call void @use32(i32 %t0)479  %t1 = shl i32 %y, %shamt1480  %t2 = and i32 %t1, %t0481  call void @use32(i32 %t2)482  %t3 = icmp ne i32 %t2, 0483  ret i1 %t3484}485define i1 @t30_var_oneuse5(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {486; CHECK-LABEL: @t30_var_oneuse5(487; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]488; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]489; CHECK-NEXT:    call void @use32(i32 [[T1]])490; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]491; CHECK-NEXT:    call void @use32(i32 [[T2]])492; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0493; CHECK-NEXT:    ret i1 [[T3]]494;495  %t0 = lshr i32 %x, %shamt0496  %t1 = shl i32 %y, %shamt1497  call void @use32(i32 %t1)498  %t2 = and i32 %t1, %t0499  call void @use32(i32 %t2)500  %t3 = icmp ne i32 %t2, 0501  ret i1 %t3502}503define i1 @t31_var_oneuse6(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {504; CHECK-LABEL: @t31_var_oneuse6(505; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]506; CHECK-NEXT:    call void @use32(i32 [[T0]])507; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]508; CHECK-NEXT:    call void @use32(i32 [[T1]])509; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]510; CHECK-NEXT:    call void @use32(i32 [[T2]])511; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0512; CHECK-NEXT:    ret i1 [[T3]]513;514  %t0 = lshr i32 %x, %shamt0515  call void @use32(i32 %t0)516  %t1 = shl i32 %y, %shamt1517  call void @use32(i32 %t1)518  %t2 = and i32 %t1, %t0519  call void @use32(i32 %t2)520  %t3 = icmp ne i32 %t2, 0521  ret i1 %t3522}523 524; Shift-of-const525 526; Ok, non-truncated shift is of constant;527define i1 @t32_shift_of_const_oneuse0(i32 %x, i32 %y, i32 %len) {528; CHECK-LABEL: @t32_shift_of_const_oneuse0(529; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[LEN:%.*]]530; CHECK-NEXT:    call void @use32(i32 [[T0]])531; CHECK-NEXT:    [[T1:%.*]] = lshr i32 -52543054, [[T0]]532; CHECK-NEXT:    call void @use32(i32 [[T1]])533; CHECK-NEXT:    [[T2:%.*]] = add i32 [[LEN]], -1534; CHECK-NEXT:    call void @use32(i32 [[T2]])535; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[Y:%.*]], [[T2]]536; CHECK-NEXT:    call void @use32(i32 [[T3]])537; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y]], 1538; CHECK-NEXT:    [[T5:%.*]] = icmp ne i32 [[TMP1]], 0539; CHECK-NEXT:    ret i1 [[T5]]540;541  %t0 = sub i32 32, %len542  call void @use32(i32 %t0)543  %t1 = lshr i32 4242424242, %t0 ; shift-of-constant544  call void @use32(i32 %t1)545  %t2 = add i32 %len, -1546  call void @use32(i32 %t2)547  %t3 = shl i32 %y, %t2548  call void @use32(i32 %t3)549  %t4 = and i32 %t1, %t3 ; no extra uses550  %t5 = icmp ne i32 %t4, 0551  ret i1 %t5552}553; Ok, truncated shift is of constant;554define i1 @t33_shift_of_const_oneuse1(i32 %x, i32 %y, i32 %len) {555; CHECK-LABEL: @t33_shift_of_const_oneuse1(556; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[LEN:%.*]]557; CHECK-NEXT:    call void @use32(i32 [[T0]])558; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[X:%.*]], [[T0]]559; CHECK-NEXT:    call void @use32(i32 [[T1]])560; CHECK-NEXT:    [[T2:%.*]] = add i32 [[LEN]], -1561; CHECK-NEXT:    call void @use32(i32 [[T2]])562; CHECK-NEXT:    [[T3:%.*]] = shl i32 -52543054, [[T2]]563; CHECK-NEXT:    call void @use32(i32 [[T3]])564; CHECK-NEXT:    ret i1 false565;566  %t0 = sub i32 32, %len567  call void @use32(i32 %t0)568  %t1 = lshr i32 %x, %t0 ; shift-of-constant569  call void @use32(i32 %t1)570  %t2 = add i32 %len, -1571  call void @use32(i32 %t2)572  %t3 = shl i32 4242424242, %t2573  call void @use32(i32 %t3)574  %t4 = and i32 %t1, %t3 ; no extra uses575  %t5 = icmp ne i32 %t4, 0576  ret i1 %t5577}578 579; Commutativity with extra uses580 581define i1 @t34_commutativity0_oneuse0(i32 %x) {582; CHECK-LABEL: @t34_commutativity0_oneuse0(583; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()584; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1585; CHECK-NEXT:    call void @use32(i32 [[T0]])586; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2587; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]588; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0589; CHECK-NEXT:    ret i1 [[T3]]590;591  %y = call i32 @gen32()592  %t0 = lshr i32 %x, 1593  call void @use32(i32 %t0)594  %t1 = shl i32 %y, 1595  %t2 = and i32 %t1, %t0596  %t3 = icmp ne i32 %t2, 0597  ret i1 %t3598}599define i1 @t35_commutativity0_oneuse1(i32 %x) {600; CHECK-LABEL: @t35_commutativity0_oneuse1(601; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()602; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y]], 1603; CHECK-NEXT:    call void @use32(i32 [[T1]])604; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2605; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]606; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0607; CHECK-NEXT:    ret i1 [[T3]]608;609  %y = call i32 @gen32()610  %t0 = lshr i32 %x, 1611  %t1 = shl i32 %y, 1612  call void @use32(i32 %t1)613  %t2 = and i32 %t1, %t0614  %t3 = icmp ne i32 %t2, 0615  ret i1 %t3616}617 618define i1 @t36_commutativity1_oneuse0(i32 %y) {619; CHECK-LABEL: @t36_commutativity1_oneuse0(620; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()621; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X]], 1622; CHECK-NEXT:    call void @use32(i32 [[T0]])623; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2624; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]625; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0626; CHECK-NEXT:    ret i1 [[T3]]627;628  %x = call i32 @gen32()629  %t0 = lshr i32 %x, 1630  call void @use32(i32 %t0)631  %t1 = shl i32 %y, 1632  %t2 = and i32 %t0, %t1 ; "swapped"633  %t3 = icmp ne i32 %t2, 0634  ret i1 %t3635}636define i1 @t37_commutativity1_oneuse1(i32 %y) {637; CHECK-LABEL: @t37_commutativity1_oneuse1(638; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()639; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1640; CHECK-NEXT:    call void @use32(i32 [[T1]])641; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2642; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]643; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0644; CHECK-NEXT:    ret i1 [[T3]]645;646  %x = call i32 @gen32()647  %t0 = lshr i32 %x, 1648  %t1 = shl i32 %y, 1649  call void @use32(i32 %t1)650  %t2 = and i32 %t0, %t1 ; "swapped"651  %t3 = icmp ne i32 %t2, 0652  ret i1 %t3653}654 655; Negative tests656define <2 x i1> @n38_overshift(<2 x i32> %x, <2 x i32> %y) {657; CHECK-LABEL: @n38_overshift(658; CHECK-NEXT:    [[T0:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 15, i32 1>659; CHECK-NEXT:    [[T1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 17, i32 1>660; CHECK-NEXT:    [[T2:%.*]] = and <2 x i32> [[T1]], [[T0]]661; CHECK-NEXT:    [[T3:%.*]] = icmp ne <2 x i32> [[T2]], zeroinitializer662; CHECK-NEXT:    ret <2 x i1> [[T3]]663;664  %t0 = lshr <2 x i32> %x, <i32 15, i32 1>665  %t1 = shl <2 x i32> %y, <i32 17, i32 1>666  %t2 = and <2 x i32> %t1, %t0667  %t3 = icmp ne <2 x i32> %t2, <i32 0, i32 0>668  ret <2 x i1> %t3669}670 671; As usual, don't crash given constantexpr's :/672@f.a = internal global i16 0, align 1673define i1 @constantexpr() {674; CHECK-LABEL: @constantexpr(675; CHECK-NEXT:  entry:676; CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @f.a, align 2677; CHECK-NEXT:    [[SHR:%.*]] = lshr i16 [[TMP0]], 1678; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 ptrtoint (ptr @f.a to i16), 1679; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i16680; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw nsw i16 1, [[ZEXT]]681; CHECK-NEXT:    [[TMP2:%.*]] = and i16 [[SHR]], [[TMP1]]682; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i16 [[TMP2]], 0683; CHECK-NEXT:    ret i1 [[TOBOOL]]684;685entry:686  %0 = load i16, ptr @f.a687  %shr = ashr i16 %0, 1688  %cmp = icmp ne i16 ptrtoint (ptr @f.a to i16), 1689  %zext = zext i1 %cmp to i16690  %shr1 = ashr i16 %shr, %zext691  %and = and i16 %shr1, 1692  %tobool = icmp ne i16 %and, 0693  ret i1 %tobool694}695 696; See https://bugs.llvm.org/show_bug.cgi?id=44802697define i1 @pr44802(i3 %a, i3 %x, i3 %y) {698; CHECK-LABEL: @pr44802(699; CHECK-NEXT:    [[T0:%.*]] = icmp ne i3 [[A:%.*]], 0700; CHECK-NEXT:    [[T1:%.*]] = zext i1 [[T0]] to i3701; CHECK-NEXT:    [[T2:%.*]] = lshr i3 [[X:%.*]], [[T1]]702; CHECK-NEXT:    [[T3:%.*]] = shl i3 [[Y:%.*]], [[T1]]703; CHECK-NEXT:    [[T4:%.*]] = and i3 [[T2]], [[T3]]704; CHECK-NEXT:    [[T5:%.*]] = icmp ne i3 [[T4]], 0705; CHECK-NEXT:    ret i1 [[T5]]706;707  %t0 = icmp ne i3 %a, 0708  %t1 = zext i1 %t0 to i3709  %t2 = lshr i3 %x, %t1710  %t3 = shl i3 %y, %t1711  %t4 = and i3 %t2, %t3712  %t5 = icmp ne i3 %t4, 0713  ret i1 %t5714}715