Home | History | Annotate | Download | only in PhaseOrdering
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt -O3 -S < %s                    | FileCheck %s
      3 ; RUN: opt -passes='default<O3>' -S < %s  | FileCheck %s
      4 
      5 ; These are tests that check for set/clear bits in a bitfield based on PR37098:
      6 ; https://bugs.llvm.org/show_bug.cgi?id=37098
      7 ;
      8 ; The initial IR from clang has been transformed by SROA, but no other passes
      9 ; have run yet. In all cases, we should reduce these to a mask and compare
     10 ; instead of shift/cast/logic ops.
     11 ;
     12 ; Currently, this happens mostly through a combination of instcombine and
     13 ; aggressive-instcombine. If pass ordering changes, we may have to adjust
     14 ; the pattern matching in 1 or both of those passes.
     15 
     16 ; Legal i32 is required to allow casting transforms that eliminate the zexts.
     17 target datalayout = "n32"
     18 
     19 define i32 @allclear(i32 %a) {
     20 ; CHECK-LABEL: @allclear(
     21 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
     22 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
     23 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
     24 ; CHECK-NEXT:    ret i32 [[TMP3]]
     25 ;
     26   %a.sroa.0.0.trunc = trunc i32 %a to i8
     27   %a.sroa.5.0.shift = lshr i32 %a, 8
     28   %bf.clear = and i8 %a.sroa.0.0.trunc, 1
     29   %bf.cast = zext i8 %bf.clear to i32
     30   %bf.lshr = lshr i8 %a.sroa.0.0.trunc, 1
     31   %bf.clear2 = and i8 %bf.lshr, 1
     32   %bf.cast3 = zext i8 %bf.clear2 to i32
     33   %or = or i32 %bf.cast, %bf.cast3
     34   %bf.lshr5 = lshr i8 %a.sroa.0.0.trunc, 2
     35   %bf.clear6 = and i8 %bf.lshr5, 1
     36   %bf.cast7 = zext i8 %bf.clear6 to i32
     37   %or8 = or i32 %or, %bf.cast7
     38   %bf.lshr10 = lshr i8 %a.sroa.0.0.trunc, 3
     39   %bf.clear11 = and i8 %bf.lshr10, 1
     40   %bf.cast12 = zext i8 %bf.clear11 to i32
     41   %or13 = or i32 %or8, %bf.cast12
     42   %cmp = icmp eq i32 %or13, 0
     43   %conv = zext i1 %cmp to i32
     44   ret i32 %conv
     45 }
     46 
     47 define i32 @anyset(i32 %a) {
     48 ; CHECK-LABEL: @anyset(
     49 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
     50 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
     51 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
     52 ; CHECK-NEXT:    ret i32 [[TMP3]]
     53 ;
     54   %a.sroa.0.0.trunc = trunc i32 %a to i8
     55   %a.sroa.5.0.shift = lshr i32 %a, 8
     56   %bf.clear = and i8 %a.sroa.0.0.trunc, 1
     57   %bf.cast = zext i8 %bf.clear to i32
     58   %bf.lshr = lshr i8 %a.sroa.0.0.trunc, 1
     59   %bf.clear2 = and i8 %bf.lshr, 1
     60   %bf.cast3 = zext i8 %bf.clear2 to i32
     61   %or = or i32 %bf.cast, %bf.cast3
     62   %bf.lshr5 = lshr i8 %a.sroa.0.0.trunc, 2
     63   %bf.clear6 = and i8 %bf.lshr5, 1
     64   %bf.cast7 = zext i8 %bf.clear6 to i32
     65   %or8 = or i32 %or, %bf.cast7
     66   %bf.lshr10 = lshr i8 %a.sroa.0.0.trunc, 3
     67   %bf.clear11 = and i8 %bf.lshr10, 1
     68   %bf.cast12 = zext i8 %bf.clear11 to i32
     69   %or13 = or i32 %or8, %bf.cast12
     70   %cmp = icmp ne i32 %or13, 0
     71   %conv = zext i1 %cmp to i32
     72   ret i32 %conv
     73 }
     74 
     75 define i32 @allset(i32 %a) {
     76 ; CHECK-LABEL: @allset(
     77 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
     78 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 15
     79 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
     80 ; CHECK-NEXT:    ret i32 [[TMP3]]
     81 ;
     82   %a.sroa.0.0.trunc = trunc i32 %a to i8
     83   %a.sroa.5.0.shift = lshr i32 %a, 8
     84   %bf.clear = and i8 %a.sroa.0.0.trunc, 1
     85   %bf.cast = zext i8 %bf.clear to i32
     86   %bf.lshr = lshr i8 %a.sroa.0.0.trunc, 1
     87   %bf.clear2 = and i8 %bf.lshr, 1
     88   %bf.cast3 = zext i8 %bf.clear2 to i32
     89   %and = and i32 %bf.cast, %bf.cast3
     90   %bf.lshr5 = lshr i8 %a.sroa.0.0.trunc, 2
     91   %bf.clear6 = and i8 %bf.lshr5, 1
     92   %bf.cast7 = zext i8 %bf.clear6 to i32
     93   %and8 = and i32 %and, %bf.cast7
     94   %bf.lshr10 = lshr i8 %a.sroa.0.0.trunc, 3
     95   %bf.clear11 = and i8 %bf.lshr10, 1
     96   %bf.cast12 = zext i8 %bf.clear11 to i32
     97   %and13 = and i32 %and8, %bf.cast12
     98   %cmp = icmp ne i32 %and13, 0
     99   %conv = zext i1 %cmp to i32
    100   ret i32 %conv
    101 }
    102 
    103 define i32 @anyclear(i32 %a) {
    104 ; CHECK-LABEL: @anyclear(
    105 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
    106 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 15
    107 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
    108 ; CHECK-NEXT:    ret i32 [[TMP3]]
    109 ;
    110   %a.sroa.0.0.trunc = trunc i32 %a to i8
    111   %a.sroa.5.0.shift = lshr i32 %a, 8
    112   %bf.clear = and i8 %a.sroa.0.0.trunc, 1
    113   %bf.cast = zext i8 %bf.clear to i32
    114   %bf.lshr = lshr i8 %a.sroa.0.0.trunc, 1
    115   %bf.clear2 = and i8 %bf.lshr, 1
    116   %bf.cast3 = zext i8 %bf.clear2 to i32
    117   %and = and i32 %bf.cast, %bf.cast3
    118   %bf.lshr5 = lshr i8 %a.sroa.0.0.trunc, 2
    119   %bf.clear6 = and i8 %bf.lshr5, 1
    120   %bf.cast7 = zext i8 %bf.clear6 to i32
    121   %and8 = and i32 %and, %bf.cast7
    122   %bf.lshr10 = lshr i8 %a.sroa.0.0.trunc, 3
    123   %bf.clear11 = and i8 %bf.lshr10, 1
    124   %bf.cast12 = zext i8 %bf.clear11 to i32
    125   %and13 = and i32 %and8, %bf.cast12
    126   %cmp = icmp eq i32 %and13, 0
    127   %conv = zext i1 %cmp to i32
    128   ret i32 %conv
    129 }
    130 
    131