brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.3 KiB · 347d355 Raw
276 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; https://bugs.llvm.org/show_bug.cgi?id=387085 6; Pattern:7;   ((1 << bits)+(-1)) u>= val8; Should be transformed into:9;   (val l>> bits) == 010 11; NOTE: the innermost shl is not one-use. Else canonicalization happens.12 13declare void @use8(i8)14declare void @use2i8(<2 x i8>)15declare void @use3i8(<3 x i8>)16 17; ============================================================================ ;18; Basic positive tests19; ============================================================================ ;20 21define i1 @p0(i8 %val, i8 %bits) {22; CHECK-LABEL: @p0(23; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]24; CHECK-NEXT:    call void @use8(i8 [[T0]])25; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL:%.*]], [[BITS]]26; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[VAL_HIGHBITS]], 027; CHECK-NEXT:    ret i1 [[R]]28;29  %t0 = shl i8 1, %bits30  call void @use8(i8 %t0)31  %t1 = add i8 %t0, -132  %r = icmp uge i8 %t1, %val33  ret i1 %r34}35 36; ============================================================================ ;37; Vector tests38; ============================================================================ ;39 40define <2 x i1> @p1_vec(<2 x i8> %val, <2 x i8> %bits) {41; CHECK-LABEL: @p1_vec(42; CHECK-NEXT:    [[T0:%.*]] = shl nuw <2 x i8> splat (i8 1), [[BITS:%.*]]43; CHECK-NEXT:    call void @use2i8(<2 x i8> [[T0]])44; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr <2 x i8> [[VAL:%.*]], [[BITS]]45; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[VAL_HIGHBITS]], zeroinitializer46; CHECK-NEXT:    ret <2 x i1> [[R]]47;48  %t0 = shl <2 x i8> <i8 1, i8 1>, %bits49  call void @use2i8(<2 x i8> %t0)50  %t1 = add <2 x i8> %t0, <i8 -1, i8 -1>51  %r = icmp uge <2 x i8> %t1, %val52  ret <2 x i1> %r53}54 55define <3 x i1> @p2_vec_undef0(<3 x i8> %val, <3 x i8> %bits) {56; CHECK-LABEL: @p2_vec_undef0(57; CHECK-NEXT:    [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]58; CHECK-NEXT:    call void @use3i8(<3 x i8> [[T0]])59; CHECK-NEXT:    [[T1:%.*]] = add <3 x i8> [[T0]], splat (i8 -1)60; CHECK-NEXT:    [[R:%.*]] = icmp uge <3 x i8> [[T1]], [[VAL:%.*]]61; CHECK-NEXT:    ret <3 x i1> [[R]]62;63  %t0 = shl <3 x i8> <i8 1, i8 undef, i8 1>, %bits64  call void @use3i8(<3 x i8> %t0)65  %t1 = add <3 x i8> %t0, <i8 -1, i8 -1, i8 -1>66  %r = icmp uge <3 x i8> %t1, %val67  ret <3 x i1> %r68}69 70define <3 x i1> @p2_vec_poison0(<3 x i8> %val, <3 x i8> %bits) {71; CHECK-LABEL: @p2_vec_poison0(72; CHECK-NEXT:    [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 poison, i8 1>, [[BITS:%.*]]73; CHECK-NEXT:    call void @use3i8(<3 x i8> [[T0]])74; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]75; CHECK-NEXT:    [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer76; CHECK-NEXT:    ret <3 x i1> [[R]]77;78  %t0 = shl <3 x i8> <i8 1, i8 poison, i8 1>, %bits79  call void @use3i8(<3 x i8> %t0)80  %t1 = add <3 x i8> %t0, <i8 -1, i8 -1, i8 -1>81  %r = icmp uge <3 x i8> %t1, %val82  ret <3 x i1> %r83}84 85define <3 x i1> @p2_vec_poison1(<3 x i8> %val, <3 x i8> %bits) {86; CHECK-LABEL: @p2_vec_poison1(87; CHECK-NEXT:    [[T0:%.*]] = shl nuw <3 x i8> splat (i8 1), [[BITS:%.*]]88; CHECK-NEXT:    call void @use3i8(<3 x i8> [[T0]])89; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]90; CHECK-NEXT:    [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer91; CHECK-NEXT:    ret <3 x i1> [[R]]92;93  %t0 = shl <3 x i8> <i8 1, i8 1, i8 1>, %bits94  call void @use3i8(<3 x i8> %t0)95  %t1 = add <3 x i8> %t0, <i8 -1, i8 poison, i8 -1>96  %r = icmp uge <3 x i8> %t1, %val97  ret <3 x i1> %r98}99 100define <3 x i1> @p2_vec_poison2(<3 x i8> %val, <3 x i8> %bits) {101; CHECK-LABEL: @p2_vec_poison2(102; CHECK-NEXT:    [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 poison, i8 1>, [[BITS:%.*]]103; CHECK-NEXT:    call void @use3i8(<3 x i8> [[T0]])104; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]105; CHECK-NEXT:    [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer106; CHECK-NEXT:    ret <3 x i1> [[R]]107;108  %t0 = shl <3 x i8> <i8 1, i8 poison, i8 1>, %bits109  call void @use3i8(<3 x i8> %t0)110  %t1 = add <3 x i8> %t0, <i8 -1, i8 poison, i8 -1>111  %r = icmp uge <3 x i8> %t1, %val112  ret <3 x i1> %r113}114 115; ============================================================================ ;116; Commutativity tests.117; ============================================================================ ;118 119declare i8 @gen8()120 121define i1 @c0(i8 %bits) {122; CHECK-LABEL: @c0(123; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]124; CHECK-NEXT:    call void @use8(i8 [[T0]])125; CHECK-NEXT:    [[VAL:%.*]] = call i8 @gen8()126; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL]], [[BITS]]127; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[VAL_HIGHBITS]], 0128; CHECK-NEXT:    ret i1 [[R]]129;130  %t0 = shl i8 1, %bits131  call void @use8(i8 %t0)132  %t1 = add i8 %t0, -1133  %val = call i8 @gen8()134  %r = icmp ule i8 %val, %t1 ; swapped order and predicate135  ret i1 %r136}137 138; What if we have the same pattern on both sides?139define i1 @both(i8 %bits0, i8 %bits1) {140; CHECK-LABEL: @both(141; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS0:%.*]]142; CHECK-NEXT:    call void @use8(i8 [[T0]])143; CHECK-NEXT:    [[T2:%.*]] = shl nuw i8 1, [[BITS1:%.*]]144; CHECK-NEXT:    call void @use8(i8 [[T2]])145; CHECK-NEXT:    [[T3:%.*]] = add i8 [[T2]], -1146; CHECK-NEXT:    [[T3_HIGHBITS:%.*]] = lshr i8 [[T3]], [[BITS0]]147; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[T3_HIGHBITS]], 0148; CHECK-NEXT:    ret i1 [[R]]149;150  %t0 = shl i8 1, %bits0151  call void @use8(i8 %t0)152  %t1 = add i8 %t0, -1153  %t2 = shl i8 1, %bits1154  call void @use8(i8 %t2)155  %t3 = add i8 %t2, -1156  %r = icmp uge i8 %t1, %t3157  ret i1 %r158}159 160; ============================================================================ ;161; One-use tests.162; ============================================================================ ;163 164define i1 @oneuse(i8 %val, i8 %bits) {165; CHECK-LABEL: @oneuse(166; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]167; CHECK-NEXT:    call void @use8(i8 [[T0]])168; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1169; CHECK-NEXT:    call void @use8(i8 [[T1]])170; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]171; CHECK-NEXT:    ret i1 [[R]]172;173  %t0 = shl i8 1, %bits174  call void @use8(i8 %t0) ; this is needed anyway175  %t1 = add i8 %t0, -1176  call void @use8(i8 %t1)177  %r = icmp uge i8 %t1, %val178  ret i1 %r179}180 181; ============================================================================ ;182; Negative tests183; ============================================================================ ;184 185define i1 @n0(i8 %val, i8 %bits) {186; CHECK-LABEL: @n0(187; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]188; CHECK-NEXT:    call void @use8(i8 [[T0]])189; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1190; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]191; CHECK-NEXT:    ret i1 [[R]]192;193  %t0 = shl i8 -1, %bits ; constant is not 1194  call void @use8(i8 %t0)195  %t1 = add i8 %t0, -1196  %r = icmp uge i8 %t1, %val197  ret i1 %r198}199 200define i1 @n1(i8 %val, i8 %bits) {201; CHECK-LABEL: @n1(202; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]203; CHECK-NEXT:    call void @use8(i8 [[T0]])204; CHECK-NEXT:    [[T1:%.*]] = add nuw i8 [[T0]], 1205; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]206; CHECK-NEXT:    ret i1 [[R]]207;208  %t0 = shl i8 1, %bits209  call void @use8(i8 %t0)210  %t1 = add i8 %t0, 1 ; constant is not -1211  %r = icmp uge i8 %t1, %val212  ret i1 %r213}214 215define <2 x i1> @n2_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {216; CHECK-LABEL: @n2_vec_nonsplat(217; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i8> <i8 1, i8 -1>, [[BITS:%.*]]218; CHECK-NEXT:    call void @use2i8(<2 x i8> [[T0]])219; CHECK-NEXT:    [[T1:%.*]] = add <2 x i8> [[T0]], splat (i8 -1)220; CHECK-NEXT:    [[R:%.*]] = icmp uge <2 x i8> [[T1]], [[VAL:%.*]]221; CHECK-NEXT:    ret <2 x i1> [[R]]222;223  %t0 = shl <2 x i8> <i8 1, i8 -1>, %bits ; again, wrong constant224  call void @use2i8(<2 x i8> %t0)225  %t1 = add <2 x i8> %t0, <i8 -1, i8 -1>226  %r = icmp uge <2 x i8> %t1, %val227  ret <2 x i1> %r228}229 230define <2 x i1> @n3_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {231; CHECK-LABEL: @n3_vec_nonsplat(232; CHECK-NEXT:    [[T0:%.*]] = shl nuw <2 x i8> splat (i8 1), [[BITS:%.*]]233; CHECK-NEXT:    call void @use2i8(<2 x i8> [[T0]])234; CHECK-NEXT:    [[T1:%.*]] = add <2 x i8> [[T0]], <i8 -1, i8 1>235; CHECK-NEXT:    [[R:%.*]] = icmp uge <2 x i8> [[T1]], [[VAL:%.*]]236; CHECK-NEXT:    ret <2 x i1> [[R]]237;238  %t0 = shl <2 x i8> <i8 1, i8 1>, %bits239  call void @use2i8(<2 x i8> %t0)240  %t1 = add <2 x i8> %t0, <i8 -1, i8 1> ; again, wrong constant241  %r = icmp uge <2 x i8> %t1, %val242  ret <2 x i1> %r243}244 245define i1 @n3(i8 %val, i8 %bits) {246; CHECK-LABEL: @n3(247; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]248; CHECK-NEXT:    call void @use8(i8 [[T0]])249; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1250; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[T1]], [[VAL:%.*]]251; CHECK-NEXT:    ret i1 [[R]]252;253  %t0 = shl i8 1, %bits254  call void @use8(i8 %t0)255  %t1 = add i8 %t0, -1256  %r = icmp ugt i8 %t1, %val ; wrong predicate257  ret i1 %r258}259 260define i1 @n4(i8 %bits) {261; CHECK-LABEL: @n4(262; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]263; CHECK-NEXT:    call void @use8(i8 [[T0]])264; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1265; CHECK-NEXT:    [[VAL:%.*]] = call i8 @gen8()266; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[VAL]], [[T1]]267; CHECK-NEXT:    ret i1 [[R]]268;269  %t0 = shl i8 1, %bits270  call void @use8(i8 %t0)271  %t1 = add i8 %t0, -1272  %val = call i8 @gen8()273  %r = icmp ult i8 %val, %t1 ; swapped order and [wrong] predicate274  ret i1 %r275}276