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