1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare i8 @llvm.fshl.i8(i8, i8, i8) 5declare i8 @llvm.fshr.i8(i8, i8, i8) 6declare <2 x i5> @llvm.fshl.v2i5(<2 x i5>, <2 x i5>, <2 x i5>) 7declare <2 x i5> @llvm.fshr.v2i5(<2 x i5>, <2 x i5>, <2 x i5>) 8declare void @use(i8) 9 10define i1 @rol_eq(i8 %x, i8 %y, i8 %z) { 11; CHECK-LABEL: @rol_eq( 12; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 13; CHECK-NEXT: ret i1 [[R]] 14; 15 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z) 16 %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z) 17 %r = icmp eq i8 %f, %f2 18 ret i1 %r 19} 20 21define i1 @rol_ne(i8 %x, i8 %y, i8 %z) { 22; CHECK-LABEL: @rol_ne( 23; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]] 24; CHECK-NEXT: ret i1 [[R]] 25; 26 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z) 27 %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z) 28 %r = icmp ne i8 %f, %f2 29 ret i1 %r 30} 31 32define i1 @ror_eq(i8 %x, i8 %y, i8 %z) { 33; CHECK-LABEL: @ror_eq( 34; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]] 35; CHECK-NEXT: ret i1 [[R]] 36; 37 %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %z) 38 %f2 = tail call i8 @llvm.fshr.i8(i8 %y, i8 %y, i8 %z) 39 %r = icmp eq i8 %f, %f2 40 ret i1 %r 41} 42 43 44define i1 @ror_ne(i8 %x, i8 %y, i8 %z) { 45; CHECK-LABEL: @ror_ne( 46; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]] 47; CHECK-NEXT: ret i1 [[R]] 48; 49 %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 %z) 50 %f2 = tail call i8 @llvm.fshr.i8(i8 %y, i8 %y, i8 %z) 51 %r = icmp ne i8 %f, %f2 52 ret i1 %r 53} 54 55define i1 @rol_eq_use(i8 %x, i8 %y, i8 %z) { 56; CHECK-LABEL: @rol_eq_use( 57; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]]) 58; CHECK-NEXT: call void @use(i8 [[F]]) 59; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[Y:%.*]] 60; CHECK-NEXT: ret i1 [[R]] 61; 62 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z) 63 call void @use(i8 %f) 64 %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z) 65 %r = icmp eq i8 %f, %f2 66 ret i1 %r 67} 68 69define i1 @rol_eq_uses(i8 %x, i8 %y, i8 %z) { 70; CHECK-LABEL: @rol_eq_uses( 71; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]]) 72; CHECK-NEXT: call void @use(i8 [[F]]) 73; CHECK-NEXT: [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y:%.*]], i8 [[Y]], i8 [[Z]]) 74; CHECK-NEXT: call void @use(i8 [[F2]]) 75; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[Y]] 76; CHECK-NEXT: ret i1 [[R]] 77; 78 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z) 79 call void @use(i8 %f) 80 %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z) 81 call void @use(i8 %f2) 82 %r = icmp eq i8 %f, %f2 83 ret i1 %r 84} 85 86define <2 x i1> @rol_eq_vec(<2 x i5> %x, <2 x i5> %y, <2 x i5> %z) { 87; CHECK-LABEL: @rol_eq_vec( 88; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], [[Y:%.*]] 89; CHECK-NEXT: ret <2 x i1> [[R]] 90; 91 %f = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> %z) 92 %f2 = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %y, <2 x i5> %y, <2 x i5> %z) 93 %r = icmp eq <2 x i5> %f, %f2 94 ret <2 x i1> %r 95} 96 97define <2 x i1> @ror_eq_vec(<2 x i5> %x, <2 x i5> %y, <2 x i5> %z) { 98; CHECK-LABEL: @ror_eq_vec( 99; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], [[Y:%.*]] 100; CHECK-NEXT: ret <2 x i1> [[R]] 101; 102 %f = tail call <2 x i5> @llvm.fshr.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> %z) 103 %f2 = tail call <2 x i5> @llvm.fshr.v2i5(<2 x i5> %y, <2 x i5> %y, <2 x i5> %z) 104 %r = icmp eq <2 x i5> %f, %f2 105 ret <2 x i1> %r 106} 107 108 109define i1 @rol_eq_cst(i8 %x) { 110; CHECK-LABEL: @rol_eq_cst( 111; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 64 112; CHECK-NEXT: ret i1 [[R]] 113; 114 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3) 115 %r = icmp eq i8 %f, 2 116 ret i1 %r 117} 118 119define i1 @rol_ne_cst(i8 %x) { 120; CHECK-LABEL: @rol_ne_cst( 121; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], 64 122; CHECK-NEXT: ret i1 [[R]] 123; 124 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3) 125 %r = icmp ne i8 %f, 2 126 ret i1 %r 127} 128 129define i1 @rol_eq_cst_use(i8 %x) { 130; CHECK-LABEL: @rol_eq_cst_use( 131; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 3) 132; CHECK-NEXT: call void @use(i8 [[F]]) 133; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], 64 134; CHECK-NEXT: ret i1 [[R]] 135; 136 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3) 137 call void @use(i8 %f) 138 %r = icmp eq i8 %f, 2 139 ret i1 %r 140} 141 142define i1 @ror_eq_cst(i8 %x) { 143; CHECK-LABEL: @ror_eq_cst( 144; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 12 145; CHECK-NEXT: ret i1 [[R]] 146; 147 %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 2) 148 %r = icmp eq i8 %f, 3 149 ret i1 %r 150} 151 152define i1 @ror_ne_cst(i8 %x) { 153; CHECK-LABEL: @ror_ne_cst( 154; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], 12 155; CHECK-NEXT: ret i1 [[R]] 156; 157 %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 2) 158 %r = icmp ne i8 %f, 3 159 ret i1 %r 160} 161 162define <2 x i1> @rol_eq_cst_vec(<2 x i5> %x) { 163; CHECK-LABEL: @rol_eq_cst_vec( 164; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[X:%.*]], splat (i5 8) 165; CHECK-NEXT: ret <2 x i1> [[R]] 166; 167 %f = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> <i5 3, i5 3>) 168 %r = icmp eq <2 x i5> %f, <i5 2, i5 2> 169 ret <2 x i1> %r 170} 171 172define <2 x i1> @rol_eq_cst_undef(<2 x i5> %x) { 173; CHECK-LABEL: @rol_eq_cst_undef( 174; CHECK-NEXT: [[F:%.*]] = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> [[X:%.*]], <2 x i5> [[X]], <2 x i5> splat (i5 3)) 175; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i5> [[F]], <i5 2, i5 undef> 176; CHECK-NEXT: ret <2 x i1> [[R]] 177; 178 %f = tail call <2 x i5> @llvm.fshl.v2i5(<2 x i5> %x, <2 x i5> %x, <2 x i5> <i5 3, i5 3>) 179 %r = icmp eq <2 x i5> %f, <i5 2, i5 undef> 180 ret <2 x i1> %r 181} 182 183; negative test - not a rotate 184define i1 @no_rotate(i8 %x, i8 %y, i8 %z) { 185; CHECK-LABEL: @no_rotate( 186; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) 187; CHECK-NEXT: [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y]], i8 [[Y]], i8 [[Z]]) 188; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[F]], [[F2]] 189; CHECK-NEXT: ret i1 [[R]] 190; 191 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %z) 192 %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z) 193 %r = icmp eq i8 %f, %f2 194 ret i1 %r 195} 196 197; negative test - wrong predicate 198define i1 @wrong_pred(i8 %x, i8 %y, i8 %z) { 199; CHECK-LABEL: @wrong_pred( 200; CHECK-NEXT: [[F:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Z:%.*]]) 201; CHECK-NEXT: [[F2:%.*]] = tail call i8 @llvm.fshl.i8(i8 [[Y:%.*]], i8 [[Y]], i8 [[Z]]) 202; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[F]], [[F2]] 203; CHECK-NEXT: ret i1 [[R]] 204; 205 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z) 206 %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %z) 207 %r = icmp ult i8 %f, %f2 208 ret i1 %r 209} 210 211; negative test - rotate amounts mismatch 212define i1 @amounts_mismatch(i8 %x, i8 %y, i8 %z, i8 %w) { 213; CHECK-LABEL: @amounts_mismatch( 214; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[Z:%.*]], [[W:%.*]] 215; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[TMP1]]) 216; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP2]] 217; CHECK-NEXT: ret i1 [[R]] 218; 219 %f = tail call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 %z) 220 %f2 = tail call i8 @llvm.fshl.i8(i8 %y, i8 %y, i8 %w) 221 %r = icmp eq i8 %f, %f2 222 ret i1 %r 223} 224 225; negative test - wrong predicate 226define i1 @wrong_pred2(i8 %x) { 227; CHECK-LABEL: @wrong_pred2( 228; CHECK-NEXT: [[F:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 5) 229; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[F]], 2 230; CHECK-NEXT: ret i1 [[R]] 231; 232 %f = tail call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 27) 233 %r = icmp ugt i8 %f, 2 234 ret i1 %r 235} 236