1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; Don't do anything for the fully-variable case. 5define i4 @t0(i4 %x, i4 %y, i4 %z) { 6; CHECK-LABEL: @t0( 7; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], [[Y:%.*]] 8; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], [[Z:%.*]] 9; CHECK-NEXT: ret i4 [[I1]] 10; 11 %i0 = or i4 %x, %y 12 %i1 = xor i4 %i0, %z 13 ret i4 %i1 14} 15 16; If the second operands are immediate constants, we can perform the fold. 17define i4 @t1(i4 %x) { 18; CHECK-LABEL: @t1( 19; CHECK-NEXT: [[TMP1:%.*]] = and i4 [[X:%.*]], 3 20; CHECK-NEXT: [[I1:%.*]] = xor i4 [[TMP1]], 6 21; CHECK-NEXT: ret i4 [[I1]] 22; 23 %i0 = or i4 %x, 12 ; 0b1100 24 %i1 = xor i4 %i0, 10 ; 0b1010 25 ret i4 %i1 26} 27 28; Must not have extra uses. 29define i4 @t2(i4 %x) { 30; CHECK-LABEL: @t2( 31; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], -4 32; CHECK-NEXT: call void @use(i4 [[I0]]) 33; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], -6 34; CHECK-NEXT: ret i4 [[I1]] 35; 36 %i0 = or i4 %x, 12 ; 0b1100 37 call void @use(i4 %i0) 38 %i1 = xor i4 %i0, 10 ; 0b1010 39 ret i4 %i1 40} 41 42; Splat constants are fine too. 43define <2 x i4> @t3(<2 x i4> %x) { 44; CHECK-LABEL: @t3( 45; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], splat (i4 3) 46; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 6) 47; CHECK-NEXT: ret <2 x i4> [[I1]] 48; 49 %i0 = or <2 x i4> %x, <i4 12, i4 12> 50 %i1 = xor <2 x i4> %i0, <i4 10, i4 10> 51 ret <2 x i4> %i1 52} 53 54; Non-splat constants are fine too. 55define <2 x i4> @t4(<2 x i4> %x) { 56; CHECK-LABEL: @t4( 57; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 5> 58; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 6) 59; CHECK-NEXT: ret <2 x i4> [[I1]] 60; 61 %i0 = or <2 x i4> %x, <i4 12, i4 10> 62 %i1 = xor <2 x i4> %i0, <i4 10, i4 12> 63 ret <2 x i4> %i1 64} 65 66; Partially-undef constants are fine. 67define <2 x i4> @t5(<2 x i4> %x) { 68; CHECK-LABEL: @t5( 69; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 undef> 70; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 undef> 71; CHECK-NEXT: ret <2 x i4> [[I1]] 72; 73 %i0 = or <2 x i4> %x, <i4 12, i4 12> 74 %i1 = xor <2 x i4> %i0, <i4 10, i4 undef> 75 ret <2 x i4> %i1 76} 77define <2 x i4> @t6(<2 x i4> %x) { 78; CHECK-LABEL: @t6( 79; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 0> 80; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 5> 81; CHECK-NEXT: ret <2 x i4> [[I1]] 82; 83 %i0 = or <2 x i4> %x, <i4 12, i4 undef> 84 %i1 = xor <2 x i4> %i0, <i4 10, i4 10> 85 ret <2 x i4> %i1 86} 87define <2 x i4> @t7(<2 x i4> %x) { 88; CHECK-LABEL: @t7( 89; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 undef> 90; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 undef> 91; CHECK-NEXT: ret <2 x i4> [[I1]] 92; 93 %i0 = or <2 x i4> %x, <i4 12, i4 undef> 94 %i1 = xor <2 x i4> %i0, <i4 10, i4 undef> 95 ret <2 x i4> %i1 96} 97 98; Partially-poison constants are fine. 99define <2 x i4> @t8(<2 x i4> %x) { 100; CHECK-LABEL: @t8( 101; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 undef> 102; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 poison> 103; CHECK-NEXT: ret <2 x i4> [[I1]] 104; 105 %i0 = or <2 x i4> %x, <i4 12, i4 12> 106 %i1 = xor <2 x i4> %i0, <i4 10, i4 poison> 107 ret <2 x i4> %i1 108} 109define <2 x i4> @t9(<2 x i4> %x) { 110; CHECK-LABEL: @t9( 111; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 0> 112; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 5> 113; CHECK-NEXT: ret <2 x i4> [[I1]] 114; 115 %i0 = or <2 x i4> %x, <i4 12, i4 poison> 116 %i1 = xor <2 x i4> %i0, <i4 10, i4 10> 117 ret <2 x i4> %i1 118} 119define <2 x i4> @t10(<2 x i4> %x) { 120; CHECK-LABEL: @t10( 121; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], <i4 3, i4 undef> 122; CHECK-NEXT: [[I1:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 poison> 123; CHECK-NEXT: ret <2 x i4> [[I1]] 124; 125 %i0 = or <2 x i4> %x, <i4 12, i4 poison> 126 %i1 = xor <2 x i4> %i0, <i4 10, i4 poison> 127 ret <2 x i4> %i1 128} 129 130; Do not deal with general constant expressions. 131@G = external global i32 132@G2 = external global i32 133define i4 @t11(i4 %x) { 134; CHECK-LABEL: @t11( 135; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], -4 136; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], ptrtoint (ptr @G2 to i4) 137; CHECK-NEXT: ret i4 [[I1]] 138; 139 %i0 = or i4 %x, 12 140 %i1 = xor i4 %i0, ptrtoint (ptr @G2 to i4) 141 ret i4 %i1 142} 143define i4 @t12(i4 %x) { 144; CHECK-LABEL: @t12( 145; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], ptrtoint (ptr @G to i4) 146; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], -6 147; CHECK-NEXT: ret i4 [[I1]] 148; 149 %i0 = or i4 %x, ptrtoint (ptr @G to i4) 150 %i1 = xor i4 %i0, 10 151 ret i4 %i1 152} 153define i4 @t13(i4 %x) { 154; CHECK-LABEL: @t13( 155; CHECK-NEXT: [[I0:%.*]] = or i4 [[X:%.*]], ptrtoint (ptr @G to i4) 156; CHECK-NEXT: [[I1:%.*]] = xor i4 [[I0]], ptrtoint (ptr @G2 to i4) 157; CHECK-NEXT: ret i4 [[I1]] 158; 159 %i0 = or i4 %x, ptrtoint (ptr @G to i4) 160 %i1 = xor i4 %i0, ptrtoint (ptr @G2 to i4) 161 ret i4 %i1 162} 163 164declare void @use(i4) 165