1; NOTE: Assertions have been autogenerated by update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define i32 @func1(i32 %a, i32 %b) { 5; CHECK-LABEL: @func1( 6; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, 1 7; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP1]], %b 8; CHECK-NEXT: ret i32 [[TMP3]] 9; 10 %tmp = or i32 %b, %a 11 %tmp1 = and i32 %tmp, 1 12 %tmp2 = and i32 %b, -2 13 %tmp3 = or i32 %tmp1, %tmp2 14 ret i32 %tmp3 15} 16 17define i32 @func2(i32 %a, i32 %b) { 18; CHECK-LABEL: @func2( 19; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, 1 20; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP1]], %b 21; CHECK-NEXT: ret i32 [[TMP3]] 22; 23 %tmp = or i32 %a, %b 24 %tmp1 = and i32 1, %tmp 25 %tmp2 = and i32 -2, %b 26 %tmp3 = or i32 %tmp1, %tmp2 27 ret i32 %tmp3 28} 29 30define i32 @func3(i32 %a, i32 %b) { 31; CHECK-LABEL: @func3( 32; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, 1 33; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP1]], %b 34; CHECK-NEXT: ret i32 [[TMP3]] 35; 36 %tmp = or i32 %b, %a 37 %tmp1 = and i32 %tmp, 1 38 %tmp2 = and i32 %b, -2 39 %tmp3 = or i32 %tmp2, %tmp1 40 ret i32 %tmp3 41} 42 43define i32 @func4(i32 %a, i32 %b) { 44; CHECK-LABEL: @func4( 45; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, 1 46; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP1]], %b 47; CHECK-NEXT: ret i32 [[TMP3]] 48; 49 %tmp = or i32 %a, %b 50 %tmp1 = and i32 1, %tmp 51 %tmp2 = and i32 -2, %b 52 %tmp3 = or i32 %tmp2, %tmp1 53 ret i32 %tmp3 54} 55 56; Check variants of: 57; and ({x}or X, Y), C --> {x}or X, (and Y, C) 58; ...in the following 5 tests. 59 60define i8 @and_or_hoist_mask(i8 %a, i8 %b) { 61; CHECK-LABEL: @and_or_hoist_mask( 62; CHECK-NEXT: [[SH:%.*]] = lshr i8 %a, 6 63; CHECK-NEXT: [[B_MASKED:%.*]] = and i8 %b, 3 64; CHECK-NEXT: [[AND:%.*]] = or i8 [[SH]], [[B_MASKED]] 65; CHECK-NEXT: ret i8 [[AND]] 66; 67 %sh = lshr i8 %a, 6 68 %or = or i8 %sh, %b 69 %and = and i8 %or, 3 70 ret i8 %and 71} 72 73define <2 x i8> @and_xor_hoist_mask_vec_splat(<2 x i8> %a, <2 x i8> %b) { 74; CHECK-LABEL: @and_xor_hoist_mask_vec_splat( 75; CHECK-NEXT: [[SH:%.*]] = lshr <2 x i8> %a, <i8 6, i8 6> 76; CHECK-NEXT: [[B_MASKED:%.*]] = and <2 x i8> %b, <i8 3, i8 3> 77; CHECK-NEXT: [[AND:%.*]] = xor <2 x i8> [[SH]], [[B_MASKED]] 78; CHECK-NEXT: ret <2 x i8> [[AND]] 79; 80 %sh = lshr <2 x i8> %a, <i8 6, i8 6> 81 %xor = xor <2 x i8> %sh, %b 82 %and = and <2 x i8> %xor, <i8 3, i8 3> 83 ret <2 x i8> %and 84} 85 86define i8 @and_xor_hoist_mask_commute(i8 %a, i8 %b) { 87; CHECK-LABEL: @and_xor_hoist_mask_commute( 88; CHECK-NEXT: [[C:%.*]] = mul i8 %b, 43 89; CHECK-NEXT: [[SH:%.*]] = lshr i8 %a, 6 90; CHECK-NEXT: [[C_MASKED:%.*]] = and i8 [[C]], 3 91; CHECK-NEXT: [[AND:%.*]] = xor i8 [[C_MASKED]], [[SH]] 92; CHECK-NEXT: ret i8 [[AND]] 93; 94 %c = mul i8 %b, 43 ; thwart complexity-based ordering 95 %sh = lshr i8 %a, 6 96 %xor = xor i8 %c, %sh 97 %and = and i8 %xor, 3 98 ret i8 %and 99} 100 101define <2 x i8> @and_or_hoist_mask_commute_vec_splat(<2 x i8> %a, <2 x i8> %b) { 102; CHECK-LABEL: @and_or_hoist_mask_commute_vec_splat( 103; CHECK-NEXT: [[C:%.*]] = mul <2 x i8> %b, <i8 43, i8 43> 104; CHECK-NEXT: [[SH:%.*]] = lshr <2 x i8> %a, <i8 6, i8 6> 105; CHECK-NEXT: [[C_MASKED:%.*]] = and <2 x i8> [[C]], <i8 3, i8 3> 106; CHECK-NEXT: [[AND:%.*]] = or <2 x i8> [[C_MASKED]], [[SH]] 107; CHECK-NEXT: ret <2 x i8> [[AND]] 108; 109 %c = mul <2 x i8> %b, <i8 43, i8 43> ; thwart complexity-based ordering 110 %sh = lshr <2 x i8> %a, <i8 6, i8 6> 111 %or = or <2 x i8> %c, %sh 112 %and = and <2 x i8> %or, <i8 3, i8 3> 113 ret <2 x i8> %and 114} 115 116; Don't transform if the 'or' has multiple uses because that would increase instruction count. 117 118define i8 @and_or_do_not_hoist_mask(i8 %a, i8 %b) { 119; CHECK-LABEL: @and_or_do_not_hoist_mask( 120; CHECK-NEXT: [[SH:%.*]] = lshr i8 %a, 6 121; CHECK-NEXT: [[OR:%.*]] = or i8 [[SH]], %b 122; CHECK-NEXT: [[AND:%.*]] = and i8 [[OR]], 3 123; CHECK-NEXT: [[EXTRA_USE_OF_OR:%.*]] = mul i8 [[OR]], [[AND]] 124; CHECK-NEXT: ret i8 [[EXTRA_USE_OF_OR]] 125; 126 %sh = lshr i8 %a, 6 127 %or = or i8 %sh, %b 128 %and = and i8 %or, 3 129 %extra_use_of_or = mul i8 %or, %and 130 ret i8 %extra_use_of_or 131} 132 133