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. 17target datalayout = "n32" 18 19define 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 47define 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 75define 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 103define 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