1 ; RUN: llc < %s -march=cellspu > %t1.s 2 ; RUN: grep eqv %t1.s | count 18 3 ; RUN: grep xshw %t1.s | count 6 4 ; RUN: grep xsbh %t1.s | count 3 5 ; RUN: grep andi %t1.s | count 3 6 7 ; Test the 'eqv' instruction, whose boolean expression is: 8 ; (a & b) | (~a & ~b), which simplifies to 9 ; (a & b) | ~(a | b) 10 ; Alternatively, a ^ ~b, which the compiler will also match. 11 12 ; ModuleID = 'eqv.bc' 13 target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" 14 target triple = "spu" 15 16 define <4 x i32> @equiv_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) { 17 %A = and <4 x i32> %arg1, %arg2 18 %B = or <4 x i32> %arg1, %arg2 19 %Bnot = xor <4 x i32> %B, < i32 -1, i32 -1, i32 -1, i32 -1 > 20 %C = or <4 x i32> %A, %Bnot 21 ret <4 x i32> %C 22 } 23 24 define <4 x i32> @equiv_v4i32_2(<4 x i32> %arg1, <4 x i32> %arg2) { 25 %B = or <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1] 26 %Bnot = xor <4 x i32> %B, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1] 27 %A = and <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1] 28 %C = or <4 x i32> %A, %Bnot ; <<4 x i32>> [#uses=1] 29 ret <4 x i32> %C 30 } 31 32 define <4 x i32> @equiv_v4i32_3(<4 x i32> %arg1, <4 x i32> %arg2) { 33 %B = or <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1] 34 %A = and <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1] 35 %Bnot = xor <4 x i32> %B, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1] 36 %C = or <4 x i32> %A, %Bnot ; <<4 x i32>> [#uses=1] 37 ret <4 x i32> %C 38 } 39 40 define <4 x i32> @equiv_v4i32_4(<4 x i32> %arg1, <4 x i32> %arg2) { 41 %arg2not = xor <4 x i32> %arg2, < i32 -1, i32 -1, i32 -1, i32 -1 > 42 %C = xor <4 x i32> %arg1, %arg2not 43 ret <4 x i32> %C 44 } 45 46 define i32 @equiv_i32_1(i32 %arg1, i32 %arg2) { 47 %A = and i32 %arg1, %arg2 ; <i32> [#uses=1] 48 %B = or i32 %arg1, %arg2 ; <i32> [#uses=1] 49 %Bnot = xor i32 %B, -1 ; <i32> [#uses=1] 50 %C = or i32 %A, %Bnot ; <i32> [#uses=1] 51 ret i32 %C 52 } 53 54 define i32 @equiv_i32_2(i32 %arg1, i32 %arg2) { 55 %B = or i32 %arg1, %arg2 ; <i32> [#uses=1] 56 %Bnot = xor i32 %B, -1 ; <i32> [#uses=1] 57 %A = and i32 %arg1, %arg2 ; <i32> [#uses=1] 58 %C = or i32 %A, %Bnot ; <i32> [#uses=1] 59 ret i32 %C 60 } 61 62 define i32 @equiv_i32_3(i32 %arg1, i32 %arg2) { 63 %B = or i32 %arg1, %arg2 ; <i32> [#uses=1] 64 %A = and i32 %arg1, %arg2 ; <i32> [#uses=1] 65 %Bnot = xor i32 %B, -1 ; <i32> [#uses=1] 66 %C = or i32 %A, %Bnot ; <i32> [#uses=1] 67 ret i32 %C 68 } 69 70 define i32 @equiv_i32_4(i32 %arg1, i32 %arg2) { 71 %arg2not = xor i32 %arg2, -1 72 %C = xor i32 %arg1, %arg2not 73 ret i32 %C 74 } 75 76 define i32 @equiv_i32_5(i32 %arg1, i32 %arg2) { 77 %arg1not = xor i32 %arg1, -1 78 %C = xor i32 %arg2, %arg1not 79 ret i32 %C 80 } 81 82 define signext i16 @equiv_i16_1(i16 signext %arg1, i16 signext %arg2) { 83 %A = and i16 %arg1, %arg2 ; <i16> [#uses=1] 84 %B = or i16 %arg1, %arg2 ; <i16> [#uses=1] 85 %Bnot = xor i16 %B, -1 ; <i16> [#uses=1] 86 %C = or i16 %A, %Bnot ; <i16> [#uses=1] 87 ret i16 %C 88 } 89 90 define signext i16 @equiv_i16_2(i16 signext %arg1, i16 signext %arg2) { 91 %B = or i16 %arg1, %arg2 ; <i16> [#uses=1] 92 %Bnot = xor i16 %B, -1 ; <i16> [#uses=1] 93 %A = and i16 %arg1, %arg2 ; <i16> [#uses=1] 94 %C = or i16 %A, %Bnot ; <i16> [#uses=1] 95 ret i16 %C 96 } 97 98 define signext i16 @equiv_i16_3(i16 signext %arg1, i16 signext %arg2) { 99 %B = or i16 %arg1, %arg2 ; <i16> [#uses=1] 100 %A = and i16 %arg1, %arg2 ; <i16> [#uses=1] 101 %Bnot = xor i16 %B, -1 ; <i16> [#uses=1] 102 %C = or i16 %A, %Bnot ; <i16> [#uses=1] 103 ret i16 %C 104 } 105 106 define signext i8 @equiv_i8_1(i8 signext %arg1, i8 signext %arg2) { 107 %A = and i8 %arg1, %arg2 ; <i8> [#uses=1] 108 %B = or i8 %arg1, %arg2 ; <i8> [#uses=1] 109 %Bnot = xor i8 %B, -1 ; <i8> [#uses=1] 110 %C = or i8 %A, %Bnot ; <i8> [#uses=1] 111 ret i8 %C 112 } 113 114 define signext i8 @equiv_i8_2(i8 signext %arg1, i8 signext %arg2) { 115 %B = or i8 %arg1, %arg2 ; <i8> [#uses=1] 116 %Bnot = xor i8 %B, -1 ; <i8> [#uses=1] 117 %A = and i8 %arg1, %arg2 ; <i8> [#uses=1] 118 %C = or i8 %A, %Bnot ; <i8> [#uses=1] 119 ret i8 %C 120 } 121 122 define signext i8 @equiv_i8_3(i8 signext %arg1, i8 signext %arg2) { 123 %B = or i8 %arg1, %arg2 ; <i8> [#uses=1] 124 %A = and i8 %arg1, %arg2 ; <i8> [#uses=1] 125 %Bnot = xor i8 %B, -1 ; <i8> [#uses=1] 126 %C = or i8 %A, %Bnot ; <i8> [#uses=1] 127 ret i8 %C 128 } 129 130 define zeroext i8 @equiv_u8_1(i8 zeroext %arg1, i8 zeroext %arg2) { 131 %A = and i8 %arg1, %arg2 ; <i8> [#uses=1] 132 %B = or i8 %arg1, %arg2 ; <i8> [#uses=1] 133 %Bnot = xor i8 %B, -1 ; <i8> [#uses=1] 134 %C = or i8 %A, %Bnot ; <i8> [#uses=1] 135 ret i8 %C 136 } 137 138 define zeroext i8 @equiv_u8_2(i8 zeroext %arg1, i8 zeroext %arg2) { 139 %B = or i8 %arg1, %arg2 ; <i8> [#uses=1] 140 %Bnot = xor i8 %B, -1 ; <i8> [#uses=1] 141 %A = and i8 %arg1, %arg2 ; <i8> [#uses=1] 142 %C = or i8 %A, %Bnot ; <i8> [#uses=1] 143 ret i8 %C 144 } 145 146 define zeroext i8 @equiv_u8_3(i8 zeroext %arg1, i8 zeroext %arg2) { 147 %B = or i8 %arg1, %arg2 ; <i8> [#uses=1] 148 %A = and i8 %arg1, %arg2 ; <i8> [#uses=1] 149 %Bnot = xor i8 %B, -1 ; <i8> [#uses=1] 150 %C = or i8 %A, %Bnot ; <i8> [#uses=1] 151 ret i8 %C 152 } 153