blob: 82dc8451382f8209aec6de52b817d4701ee31b67 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -debugify -loop-idiom -mtriple=x86_64 -mcpu=core-avx2 < %s -S | FileCheck --check-prefixes=ALL,LZCNT %s
; RUN: opt -debugify -loop-idiom -mtriple=x86_64 -mcpu=corei7 < %s -S | FileCheck --check-prefixes=ALL,NOLZCNT %s
declare i32 @gen32()
declare void @use32(i32)
declare void @use1(i1)
declare void @external_side_effect()
; The patterns here are all have the same base form:
; while (!(x & (1U << bit)))
; x <<= 1;
; .. which is an uncountable loop.
; We should transform it into it's countable form.
; Most basic example.
define i32 @p0_i32(i32 %x, i32 %bit) {
; LZCNT-LABEL: @p0_i32(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG16:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META9:metadata !.*]], metadata !DIExpression()), [[DBG16]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG17:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG17]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG17]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG17]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG17]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG17]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG17]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG17]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG17]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG17]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG18:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG17]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG17]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META11:metadata !.*]], metadata !DIExpression()), [[DBG17]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG19:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META12:metadata !.*]], metadata !DIExpression()), [[DBG19]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG20:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META13:metadata !.*]], metadata !DIExpression()), [[DBG20]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG21:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META15:metadata !.*]], metadata !DIExpression()), [[DBG21]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG22:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG22]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG22]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG17]]
; LZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG23:!dbg !.*]]
;
; NOLZCNT-LABEL: @p0_i32(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG16:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META9:metadata !.*]], metadata !DIExpression()), [[DBG16]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG17:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG18:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META11:metadata !.*]], metadata !DIExpression()), [[DBG18]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG19:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META12:metadata !.*]], metadata !DIExpression()), [[DBG19]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG20:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META13:metadata !.*]], metadata !DIExpression()), [[DBG20]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG21:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META15:metadata !.*]], metadata !DIExpression()), [[DBG21]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG22:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG18]]
; NOLZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG23:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; Same, but in some other bit width.
define i16 @p1_i16(i16 %x, i16 %bit) {
; LZCNT-LABEL: @p1_i16(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i16 1, [[BIT:%.*]], [[DBG32:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i16 [[BITMASK]], [[META26:metadata !.*]], metadata !DIExpression()), [[DBG32]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i16 [[BITMASK]], -1, [[DBG33:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i16 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG33]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i16 [[X:%.*]], [[BIT_MASK]], [[DBG33]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X_MASKED]], i1 true), [[DBG33]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i16 16, [[X_MASKED_NUMLEADINGZEROS]], [[DBG33]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i16 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG33]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i16 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG33]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i16 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG33]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i16 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG33]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i16 [[X_CURR]], 1, [[DBG33]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG34:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG33]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i16 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG33]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i16 [[TMP0]], [[META28:metadata !.*]], metadata !DIExpression()), [[DBG33]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i16 [[TMP0]], [[BITMASK]], [[DBG35:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i16 [[X_CURR_BITMASKED]], [[META29:metadata !.*]], metadata !DIExpression()), [[DBG35]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i16 [[X_CURR_BITMASKED]], 0, [[DBG36:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META30:metadata !.*]], metadata !DIExpression()), [[DBG36]]
; LZCNT-NEXT: [[TMP1]] = shl i16 [[TMP0]], 1, [[DBG37:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i16 [[TMP1]], [[META31:metadata !.*]], metadata !DIExpression()), [[DBG37]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i16 [[LOOP_IV]], 1, [[DBG38:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i16 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG38]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG38]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i16 [ [[X_CURR]], [[LOOP]] ], [[DBG33]]
; LZCNT-NEXT: ret i16 [[X_CURR_LCSSA]], [[DBG39:!dbg !.*]]
;
; NOLZCNT-LABEL: @p1_i16(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i16 1, [[BIT:%.*]], [[DBG32:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i16 [[BITMASK]], [[META26:metadata !.*]], metadata !DIExpression()), [[DBG32]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG33:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i16 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG34:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i16 [[X_CURR]], [[META28:metadata !.*]], metadata !DIExpression()), [[DBG34]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i16 [[X_CURR]], [[BITMASK]], [[DBG35:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i16 [[X_CURR_BITMASKED]], [[META29:metadata !.*]], metadata !DIExpression()), [[DBG35]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i16 [[X_CURR_BITMASKED]], 0, [[DBG36:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META30:metadata !.*]], metadata !DIExpression()), [[DBG36]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i16 [[X_CURR]], 1, [[DBG37:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i16 [[X_NEXT]], [[META31:metadata !.*]], metadata !DIExpression()), [[DBG37]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG38:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i16 [ [[X_CURR]], [[LOOP]] ], [[DBG34]]
; NOLZCNT-NEXT: ret i16 [[X_CURR_LCSSA]], [[DBG39:!dbg !.*]]
;
entry:
%bitmask = shl i16 1, %bit
br label %loop
loop:
%x.curr = phi i16 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i16 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i16 %x.curr.bitmasked, 0
%x.next = shl i16 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i16 %x.curr
}
; We don't particularly care whether %x.curr or %x.curr will live-out.
define i32 @p2_different_liveout(i32 %x, i32 %bit) {
; LZCNT-LABEL: @p2_different_liveout(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG47:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META42:metadata !.*]], metadata !DIExpression()), [[DBG47]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG48:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG48]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG48]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG48]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG48]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG48]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG48]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG48]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG48]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG48]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG49:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG48]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG48]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META43:metadata !.*]], metadata !DIExpression()), [[DBG48]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG50:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META44:metadata !.*]], metadata !DIExpression()), [[DBG50]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG51:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META45:metadata !.*]], metadata !DIExpression()), [[DBG51]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG52:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META46:metadata !.*]], metadata !DIExpression()), [[DBG52]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG53:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG53]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG53]]
; LZCNT: end:
; LZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG52]]
; LZCNT-NEXT: ret i32 [[X_NEXT_LCSSA]], [[DBG54:!dbg !.*]]
;
; NOLZCNT-LABEL: @p2_different_liveout(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG47:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META42:metadata !.*]], metadata !DIExpression()), [[DBG47]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG48:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG49:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META43:metadata !.*]], metadata !DIExpression()), [[DBG49]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG50:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META44:metadata !.*]], metadata !DIExpression()), [[DBG50]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG51:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META45:metadata !.*]], metadata !DIExpression()), [[DBG51]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG52:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META46:metadata !.*]], metadata !DIExpression()), [[DBG52]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG53:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG52]]
; NOLZCNT-NEXT: ret i32 [[X_NEXT_LCSSA]], [[DBG54:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.next ; not %x.curr
}
; Even both of them can liveout
define void @p3_constant_mask_24thbit(i32 %x, i32* %p0, i32* %p1) {
; LZCNT-LABEL: @p3_constant_mask_24thbit(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], 33554431, [[DBG61:!dbg !.*]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG61]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG61]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG61]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 24, [[X_MASKED_LEADINGONEPOS]], [[DBG61]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG61]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG61]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X]], [[LOOP_TRIPCOUNT]], [[DBG61]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG62:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG61]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG61]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META57:metadata !.*]], metadata !DIExpression()), [[DBG61]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], 16777216, [[DBG63:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META58:metadata !.*]], metadata !DIExpression()), [[DBG63]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG64:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META59:metadata !.*]], metadata !DIExpression()), [[DBG64]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG65:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META60:metadata !.*]], metadata !DIExpression()), [[DBG65]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG66:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG66]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG66]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG61]]
; LZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG65]]
; LZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG67:!dbg !.*]]
; LZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG68:!dbg !.*]]
; LZCNT-NEXT: ret void, [[DBG69:!dbg !.*]]
;
; NOLZCNT-LABEL: @p3_constant_mask_24thbit(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG61:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG62:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META57:metadata !.*]], metadata !DIExpression()), [[DBG62]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 16777216, [[DBG63:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META58:metadata !.*]], metadata !DIExpression()), [[DBG63]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG64:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META59:metadata !.*]], metadata !DIExpression()), [[DBG64]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG65:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META60:metadata !.*]], metadata !DIExpression()), [[DBG65]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG66:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG62]]
; NOLZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG65]]
; NOLZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG67:!dbg !.*]]
; NOLZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG68:!dbg !.*]]
; NOLZCNT-NEXT: ret void, [[DBG69:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, 16777216
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
store i32 %x.curr, i32* %p0
store i32 %x.next, i32* %p1
ret void
}
define void @p4_constant_mask_15thbit(i32 %x, i32* %p0, i32* %p1) {
; LZCNT-LABEL: @p4_constant_mask_15thbit(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], 65535, [[DBG76:!dbg !.*]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG76]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG76]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG76]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 15, [[X_MASKED_LEADINGONEPOS]], [[DBG76]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG76]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG76]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X]], [[LOOP_TRIPCOUNT]], [[DBG76]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG77:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG76]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG76]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META72:metadata !.*]], metadata !DIExpression()), [[DBG76]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], 32768, [[DBG78:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META73:metadata !.*]], metadata !DIExpression()), [[DBG78]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG79:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META74:metadata !.*]], metadata !DIExpression()), [[DBG79]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG80:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META75:metadata !.*]], metadata !DIExpression()), [[DBG80]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG81:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG81]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG81]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG76]]
; LZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG80]]
; LZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG82:!dbg !.*]]
; LZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG83:!dbg !.*]]
; LZCNT-NEXT: ret void, [[DBG84:!dbg !.*]]
;
; NOLZCNT-LABEL: @p4_constant_mask_15thbit(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG76:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG77:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META72:metadata !.*]], metadata !DIExpression()), [[DBG77]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 32768, [[DBG78:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META73:metadata !.*]], metadata !DIExpression()), [[DBG78]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG79:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META74:metadata !.*]], metadata !DIExpression()), [[DBG79]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG80:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META75:metadata !.*]], metadata !DIExpression()), [[DBG80]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG81:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG77]]
; NOLZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG80]]
; NOLZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG82:!dbg !.*]]
; NOLZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG83:!dbg !.*]]
; NOLZCNT-NEXT: ret void, [[DBG84:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, 32768
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
store i32 %x.curr, i32* %p0
store i32 %x.next, i32* %p1
ret void
}
; All no-wrap flags can be kept on the shift.
define void @p5_nuw(i32 %x, i32 %bit, i32* %p0, i32* %p1) {
; LZCNT-LABEL: @p5_nuw(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG92:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META87:metadata !.*]], metadata !DIExpression()), [[DBG92]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG93:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG93]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG93]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG93]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG93]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG93]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG93]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG93]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl nuw i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG93]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl nuw i32 [[X]], [[LOOP_TRIPCOUNT]], [[DBG93]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG94:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG93]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG93]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META88:metadata !.*]], metadata !DIExpression()), [[DBG93]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG95:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META89:metadata !.*]], metadata !DIExpression()), [[DBG95]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG96:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META90:metadata !.*]], metadata !DIExpression()), [[DBG96]]
; LZCNT-NEXT: [[TMP1]] = shl nuw i32 [[TMP0]], 1, [[DBG97:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META91:metadata !.*]], metadata !DIExpression()), [[DBG97]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG98:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG98]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG98]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG93]]
; LZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG97]]
; LZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG99:!dbg !.*]]
; LZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG100:!dbg !.*]]
; LZCNT-NEXT: ret void, [[DBG101:!dbg !.*]]
;
; NOLZCNT-LABEL: @p5_nuw(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG92:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META87:metadata !.*]], metadata !DIExpression()), [[DBG92]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG93:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG94:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META88:metadata !.*]], metadata !DIExpression()), [[DBG94]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG95:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META89:metadata !.*]], metadata !DIExpression()), [[DBG95]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG96:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META90:metadata !.*]], metadata !DIExpression()), [[DBG96]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl nuw i32 [[X_CURR]], 1, [[DBG97:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META91:metadata !.*]], metadata !DIExpression()), [[DBG97]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG98:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG94]]
; NOLZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG97]]
; NOLZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG99:!dbg !.*]]
; NOLZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG100:!dbg !.*]]
; NOLZCNT-NEXT: ret void, [[DBG101:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl nuw i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
store i32 %x.curr, i32* %p0
store i32 %x.next, i32* %p1
ret void
}
define void @p6_nsw(i32 %x, i32 %bit, i32* %p0, i32* %p1) {
; LZCNT-LABEL: @p6_nsw(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG109:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META104:metadata !.*]], metadata !DIExpression()), [[DBG109]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG110:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG110]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG110]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG110]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG110]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG110]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG110]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG110]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl nsw i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG110]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl nsw i32 [[X]], [[LOOP_TRIPCOUNT]], [[DBG110]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG111:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG110]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG110]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META105:metadata !.*]], metadata !DIExpression()), [[DBG110]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG112:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META106:metadata !.*]], metadata !DIExpression()), [[DBG112]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG113:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META107:metadata !.*]], metadata !DIExpression()), [[DBG113]]
; LZCNT-NEXT: [[TMP1]] = shl nsw i32 [[TMP0]], 1, [[DBG114:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META108:metadata !.*]], metadata !DIExpression()), [[DBG114]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG115:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG115]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG115]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG110]]
; LZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG114]]
; LZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG116:!dbg !.*]]
; LZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG117:!dbg !.*]]
; LZCNT-NEXT: ret void, [[DBG118:!dbg !.*]]
;
; NOLZCNT-LABEL: @p6_nsw(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG109:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META104:metadata !.*]], metadata !DIExpression()), [[DBG109]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG110:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG111:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META105:metadata !.*]], metadata !DIExpression()), [[DBG111]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG112:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META106:metadata !.*]], metadata !DIExpression()), [[DBG112]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG113:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META107:metadata !.*]], metadata !DIExpression()), [[DBG113]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl nsw i32 [[X_CURR]], 1, [[DBG114:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META108:metadata !.*]], metadata !DIExpression()), [[DBG114]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG115:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG111]]
; NOLZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG114]]
; NOLZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG116:!dbg !.*]]
; NOLZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG117:!dbg !.*]]
; NOLZCNT-NEXT: ret void, [[DBG118:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl nsw i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
store i32 %x.curr, i32* %p0
store i32 %x.next, i32* %p1
ret void
}
define void @p7_nuwnsw(i32 %x, i32 %bit, i32* %p0, i32* %p1) {
; LZCNT-LABEL: @p7_nuwnsw(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG126:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META121:metadata !.*]], metadata !DIExpression()), [[DBG126]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG127:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG127]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG127]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG127]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG127]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG127]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG127]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG127]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl nuw nsw i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG127]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl nuw nsw i32 [[X]], [[LOOP_TRIPCOUNT]], [[DBG127]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG128:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG127]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG127]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META122:metadata !.*]], metadata !DIExpression()), [[DBG127]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG129:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META123:metadata !.*]], metadata !DIExpression()), [[DBG129]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG130:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META124:metadata !.*]], metadata !DIExpression()), [[DBG130]]
; LZCNT-NEXT: [[TMP1]] = shl nuw nsw i32 [[TMP0]], 1, [[DBG131:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META125:metadata !.*]], metadata !DIExpression()), [[DBG131]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG132:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG132]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG132]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG127]]
; LZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG131]]
; LZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG133:!dbg !.*]]
; LZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG134:!dbg !.*]]
; LZCNT-NEXT: ret void, [[DBG135:!dbg !.*]]
;
; NOLZCNT-LABEL: @p7_nuwnsw(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG126:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META121:metadata !.*]], metadata !DIExpression()), [[DBG126]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG127:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG128:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META122:metadata !.*]], metadata !DIExpression()), [[DBG128]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG129:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META123:metadata !.*]], metadata !DIExpression()), [[DBG129]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG130:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META124:metadata !.*]], metadata !DIExpression()), [[DBG130]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl nuw nsw i32 [[X_CURR]], 1, [[DBG131:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META125:metadata !.*]], metadata !DIExpression()), [[DBG131]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG132:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG128]]
; NOLZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG131]]
; NOLZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG133:!dbg !.*]]
; NOLZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG134:!dbg !.*]]
; NOLZCNT-NEXT: ret void, [[DBG135:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl nuw nsw i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
store i32 %x.curr, i32* %p0
store i32 %x.next, i32* %p1
ret void
}
define void @p8_constant_mask_signbit_noncanonical(i32 %x, i32* %p0, i32* %p1) {
; LZCNT-LABEL: @p8_constant_mask_signbit_noncanonical(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[X_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), [[DBG142:!dbg !.*]]
; LZCNT-NEXT: [[X_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_NUMLEADINGZEROS]], [[DBG142]]
; LZCNT-NEXT: [[X_LEADINGONEPOS:%.*]] = add i32 [[X_NUMACTIVEBITS]], -1, [[DBG142]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 31, [[X_LEADINGONEPOS]], [[DBG142]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG142]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG142]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG142]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG143:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG142]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG142]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META138:metadata !.*]], metadata !DIExpression()), [[DBG142]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], -2147483648, [[DBG144:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META139:metadata !.*]], metadata !DIExpression()), [[DBG144]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG145:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META140:metadata !.*]], metadata !DIExpression()), [[DBG145]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG146:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META141:metadata !.*]], metadata !DIExpression()), [[DBG146]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG147:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG147]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG147]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG142]]
; LZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG146]]
; LZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG148:!dbg !.*]]
; LZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG149:!dbg !.*]]
; LZCNT-NEXT: ret void, [[DBG150:!dbg !.*]]
;
; NOLZCNT-LABEL: @p8_constant_mask_signbit_noncanonical(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG142:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG143:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META138:metadata !.*]], metadata !DIExpression()), [[DBG143]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], -2147483648, [[DBG144:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META139:metadata !.*]], metadata !DIExpression()), [[DBG144]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG145:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META140:metadata !.*]], metadata !DIExpression()), [[DBG145]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG146:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META141:metadata !.*]], metadata !DIExpression()), [[DBG146]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG147:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG143]]
; NOLZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG146]]
; NOLZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG148:!dbg !.*]]
; NOLZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG149:!dbg !.*]]
; NOLZCNT-NEXT: ret void, [[DBG150:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, 2147483648
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
store i32 %x.curr, i32* %p0
store i32 %x.next, i32* %p1
ret void
}
define void @p9_constant_mask_signbit_canonical(i32 %x, i32* %p0, i32* %p1) {
; LZCNT-LABEL: @p9_constant_mask_signbit_canonical(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[X_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), [[DBG156:!dbg !.*]]
; LZCNT-NEXT: [[X_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_NUMLEADINGZEROS]], [[DBG156]]
; LZCNT-NEXT: [[X_LEADINGONEPOS:%.*]] = add i32 [[X_NUMACTIVEBITS]], -1, [[DBG156]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 31, [[X_LEADINGONEPOS]], [[DBG156]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG156]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG156]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG156]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG157:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG156]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG156]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META153:metadata !.*]], metadata !DIExpression()), [[DBG156]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp sgt i32 [[TMP0]], -1, [[DBG158:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META154:metadata !.*]], metadata !DIExpression()), [[DBG158]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG159:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META155:metadata !.*]], metadata !DIExpression()), [[DBG159]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG160:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG160]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG160]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG156]]
; LZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG159]]
; LZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG161:!dbg !.*]]
; LZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG162:!dbg !.*]]
; LZCNT-NEXT: ret void, [[DBG163:!dbg !.*]]
;
; NOLZCNT-LABEL: @p9_constant_mask_signbit_canonical(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG156:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG157:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META153:metadata !.*]], metadata !DIExpression()), [[DBG157]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp sgt i32 [[X_CURR]], -1, [[DBG158:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META154:metadata !.*]], metadata !DIExpression()), [[DBG158]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG159:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META155:metadata !.*]], metadata !DIExpression()), [[DBG159]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG160:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG157]]
; NOLZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG159]]
; NOLZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG161:!dbg !.*]]
; NOLZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG162:!dbg !.*]]
; NOLZCNT-NEXT: ret void, [[DBG163:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.isbitunset = icmp sgt i32 %x.curr, -1
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
store i32 %x.curr, i32* %p0
store i32 %x.next, i32* %p1
ret void
}
define void @p10_x_is_not_one(i32 %bit, i32* %p0, i32* %p1) {
; LZCNT-LABEL: @p10_x_is_not_one(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG171:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META166:metadata !.*]], metadata !DIExpression()), [[DBG171]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG172:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG172]]
; LZCNT-NEXT: [[DOTMASKED:%.*]] = and i32 2, [[BIT_MASK]], [[DBG172]]
; LZCNT-NEXT: [[DOTMASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[DOTMASKED]], i1 true), [[DBG172]]
; LZCNT-NEXT: [[DOTMASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[DOTMASKED_NUMLEADINGZEROS]], [[DBG172]]
; LZCNT-NEXT: [[DOTMASKED_LEADINGONEPOS:%.*]] = add i32 [[DOTMASKED_NUMACTIVEBITS]], -1, [[DBG172]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[DOTMASKED_LEADINGONEPOS]], [[DBG172]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG172]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 2, [[LOOP_BACKEDGETAKENCOUNT]], [[DBG172]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG172]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG173:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG172]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ 2, [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG172]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META167:metadata !.*]], metadata !DIExpression()), [[DBG172]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG174:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META168:metadata !.*]], metadata !DIExpression()), [[DBG174]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG175:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META169:metadata !.*]], metadata !DIExpression()), [[DBG175]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG176:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META170:metadata !.*]], metadata !DIExpression()), [[DBG176]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG177:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG177]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG177]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG172]]
; LZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG176]]
; LZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG178:!dbg !.*]]
; LZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG179:!dbg !.*]]
; LZCNT-NEXT: ret void, [[DBG180:!dbg !.*]]
;
; NOLZCNT-LABEL: @p10_x_is_not_one(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG171:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META166:metadata !.*]], metadata !DIExpression()), [[DBG171]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG172:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG173:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META167:metadata !.*]], metadata !DIExpression()), [[DBG173]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG174:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META168:metadata !.*]], metadata !DIExpression()), [[DBG174]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG175:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META169:metadata !.*]], metadata !DIExpression()), [[DBG175]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG176:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META170:metadata !.*]], metadata !DIExpression()), [[DBG176]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG177:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG173]]
; NOLZCNT-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG176]]
; NOLZCNT-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG178:!dbg !.*]]
; NOLZCNT-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG179:!dbg !.*]]
; NOLZCNT-NEXT: ret void, [[DBG180:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ 2, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
store i32 %x.curr, i32* %p0
store i32 %x.next, i32* %p1
ret void
}
; Check that loop backedge's cmp-br order is correctly handled
define i32 @p11(i32 %x, i32 %bit) {
; LZCNT-LABEL: @p11(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG188:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META183:metadata !.*]], metadata !DIExpression()), [[DBG188]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG189:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG189]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG189]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG189]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG189]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG189]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG189]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG189]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG189]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG189]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG190:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG189]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG189]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META184:metadata !.*]], metadata !DIExpression()), [[DBG189]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG191:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META185:metadata !.*]], metadata !DIExpression()), [[DBG191]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp ne i32 [[X_CURR_BITMASKED]], 0, [[DBG192:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META186:metadata !.*]], metadata !DIExpression()), [[DBG192]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG193:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META187:metadata !.*]], metadata !DIExpression()), [[DBG193]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG194:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG194]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG194]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG189]]
; LZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG195:!dbg !.*]]
;
; NOLZCNT-LABEL: @p11(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG188:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META183:metadata !.*]], metadata !DIExpression()), [[DBG188]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG189:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG190:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META184:metadata !.*]], metadata !DIExpression()), [[DBG190]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG191:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META185:metadata !.*]], metadata !DIExpression()), [[DBG191]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp ne i32 [[X_CURR_BITMASKED]], 0, [[DBG192:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META186:metadata !.*]], metadata !DIExpression()), [[DBG192]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG193:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META187:metadata !.*]], metadata !DIExpression()), [[DBG193]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[END:%.*]], label [[LOOP]], [[DBG194:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG190]]
; NOLZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG195:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp ne i32 %x.curr.bitmasked, 0 ; swapped predicate
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %end, label %loop ; swapped dests
end:
ret i32 %x.curr
}
; `and` is commutative, so ensure that order is irrelevant
define i32 @p12(i32 %x, i32 %bit) {
; LZCNT-LABEL: @p12(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG203:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META198:metadata !.*]], metadata !DIExpression()), [[DBG203]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG204:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG204]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG204]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG204]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG204]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG204]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG204]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG204]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG204]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG204]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG205:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG204]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG204]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META199:metadata !.*]], metadata !DIExpression()), [[DBG204]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[BITMASK]], [[TMP0]], [[DBG206:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META200:metadata !.*]], metadata !DIExpression()), [[DBG206]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG207:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META201:metadata !.*]], metadata !DIExpression()), [[DBG207]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG208:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META202:metadata !.*]], metadata !DIExpression()), [[DBG208]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG209:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG209]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG209]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG204]]
; LZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG210:!dbg !.*]]
;
; NOLZCNT-LABEL: @p12(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG203:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META198:metadata !.*]], metadata !DIExpression()), [[DBG203]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG204:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG205:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META199:metadata !.*]], metadata !DIExpression()), [[DBG205]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[BITMASK]], [[X_CURR]], [[DBG206:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META200:metadata !.*]], metadata !DIExpression()), [[DBG206]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG207:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META201:metadata !.*]], metadata !DIExpression()), [[DBG207]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG208:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META202:metadata !.*]], metadata !DIExpression()), [[DBG208]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG209:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG205]]
; NOLZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG210:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %bitmask, %x.curr ; swapped
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; PHI node does not have any particular order for it's incomings,
; but check that the other order still works.
define i32 @p13(i32 %x, i32 %bit) {
; LZCNT-LABEL: @p13(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG218:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META213:metadata !.*]], metadata !DIExpression()), [[DBG218]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG219:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG219]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG219]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG219]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG219]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG219]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG219]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG219]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG219]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG219]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG220:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG219]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[TMP1:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY]] ], [[DBG219]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META214:metadata !.*]], metadata !DIExpression()), [[DBG219]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG221:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META215:metadata !.*]], metadata !DIExpression()), [[DBG221]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG222:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META216:metadata !.*]], metadata !DIExpression()), [[DBG222]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG223:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META217:metadata !.*]], metadata !DIExpression()), [[DBG223]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG224:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG224]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG224]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG219]]
; LZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG225:!dbg !.*]]
;
; NOLZCNT-LABEL: @p13(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG218:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META213:metadata !.*]], metadata !DIExpression()), [[DBG218]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG219:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X_NEXT:%.*]], [[LOOP]] ], [ [[X:%.*]], [[ENTRY:%.*]] ], [[DBG220:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META214:metadata !.*]], metadata !DIExpression()), [[DBG220]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG221:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META215:metadata !.*]], metadata !DIExpression()), [[DBG221]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG222:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META216:metadata !.*]], metadata !DIExpression()), [[DBG222]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG223:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META217:metadata !.*]], metadata !DIExpression()), [[DBG223]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG224:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG220]]
; NOLZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG225:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x.next, %loop ], [ %x, %entry ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; ICmp-Br are commutative
define i32 @p14(i32 %x) {
; LZCNT-LABEL: @p14(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[X_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), [[DBG231:!dbg !.*]]
; LZCNT-NEXT: [[X_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_NUMLEADINGZEROS]], [[DBG231]]
; LZCNT-NEXT: [[X_LEADINGONEPOS:%.*]] = add i32 [[X_NUMACTIVEBITS]], -1, [[DBG231]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 31, [[X_LEADINGONEPOS]], [[DBG231]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG231]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG231]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG231]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG232:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG231]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG231]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META228:metadata !.*]], metadata !DIExpression()), [[DBG231]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp slt i32 [[TMP0]], 0, [[DBG233:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META229:metadata !.*]], metadata !DIExpression()), [[DBG233]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG234:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META230:metadata !.*]], metadata !DIExpression()), [[DBG234]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG235:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG235]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG235]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG231]]
; LZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG236:!dbg !.*]]
;
; NOLZCNT-LABEL: @p14(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG231:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG232:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META228:metadata !.*]], metadata !DIExpression()), [[DBG232]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp slt i32 [[X_CURR]], 0, [[DBG233:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META229:metadata !.*]], metadata !DIExpression()), [[DBG233]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG234:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META230:metadata !.*]], metadata !DIExpression()), [[DBG234]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[END:%.*]], label [[LOOP]], [[DBG235:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG232]]
; NOLZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG236:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.isbitunset = icmp slt i32 %x.curr, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %end, label %loop
end:
ret i32 %x.curr
}
;-------------------------------------------------------------------------------
; Negative tests
; The %bitmask must be outside of the loop.
define i32 @n15(i32 %x, i32 %bit) {
; ALL-LABEL: @n15(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG244:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG245:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META239:metadata !.*]], metadata !DIExpression()), [[DBG245]]
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG246:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META240:metadata !.*]], metadata !DIExpression()), [[DBG246]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG247:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META241:metadata !.*]], metadata !DIExpression()), [[DBG247]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG248:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META242:metadata !.*]], metadata !DIExpression()), [[DBG248]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG249:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META243:metadata !.*]], metadata !DIExpression()), [[DBG249]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG250:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG245]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG251:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%bitmask = shl i32 1, %bit ; not loop-invariant
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; The %bitmask must be loop-invariant
define i32 @n16(i32 %x, i32 %bit) {
; ALL-LABEL: @n16(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG259:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG260:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META254:metadata !.*]], metadata !DIExpression()), [[DBG260]]
; ALL-NEXT: [[BITMASK:%.*]] = call i32 @gen32(), [[DBG261:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META255:metadata !.*]], metadata !DIExpression()), [[DBG261]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG262:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META256:metadata !.*]], metadata !DIExpression()), [[DBG262]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG263:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META257:metadata !.*]], metadata !DIExpression()), [[DBG263]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG264:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META258:metadata !.*]], metadata !DIExpression()), [[DBG264]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG265:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG260]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG266:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%bitmask = call i32 @gen32() ; really not loop-invariant
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; The %bitmask must be a left-shift of a single bit.
define i32 @n17(i32 %x, i32 %bit) {
; ALL-LABEL: @n17(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 2, [[BIT:%.*]], [[DBG274:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META269:metadata !.*]], metadata !DIExpression()), [[DBG274]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG275:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG276:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META270:metadata !.*]], metadata !DIExpression()), [[DBG276]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG277:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META271:metadata !.*]], metadata !DIExpression()), [[DBG277]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG278:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META272:metadata !.*]], metadata !DIExpression()), [[DBG278]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG279:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META273:metadata !.*]], metadata !DIExpression()), [[DBG279]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG280:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG276]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG281:!dbg !.*]]
;
entry:
%bitmask = shl i32 2, %bit ; not what we are looking for.
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; Bad recurrence - should be a left-shift by 1.
define i32 @n18(i32 %x, i32 %bit) {
; ALL-LABEL: @n18(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG289:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META284:metadata !.*]], metadata !DIExpression()), [[DBG289]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG290:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG291:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META285:metadata !.*]], metadata !DIExpression()), [[DBG291]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG292:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META286:metadata !.*]], metadata !DIExpression()), [[DBG292]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG293:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META287:metadata !.*]], metadata !DIExpression()), [[DBG293]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 2, [[DBG294:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META288:metadata !.*]], metadata !DIExpression()), [[DBG294]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG295:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG291]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG296:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 2 ; wrong shift amount.
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; The comparison is not what we are looking for.
define i32 @n19(i32 %x, i32 %bit) {
; ALL-LABEL: @n19(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG304:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META299:metadata !.*]], metadata !DIExpression()), [[DBG304]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG305:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG306:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META300:metadata !.*]], metadata !DIExpression()), [[DBG306]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG307:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META301:metadata !.*]], metadata !DIExpression()), [[DBG307]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp ne i32 [[X_CURR_BITMASKED]], [[BITMASK]], [[DBG308:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META302:metadata !.*]], metadata !DIExpression()), [[DBG308]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG309:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META303:metadata !.*]], metadata !DIExpression()), [[DBG309]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG310:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG306]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG311:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp ne i32 %x.curr.bitmasked, %bitmask ; should be `==0`
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; We should loop while %x.curr.bitmasked is 0, not exit when it is 0.
define i32 @n20(i32 %x, i32 %bit) {
; ALL-LABEL: @n20(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG319:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META314:metadata !.*]], metadata !DIExpression()), [[DBG319]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG320:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG321:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META315:metadata !.*]], metadata !DIExpression()), [[DBG321]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG322:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META316:metadata !.*]], metadata !DIExpression()), [[DBG322]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG323:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META317:metadata !.*]], metadata !DIExpression()), [[DBG323]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG324:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META318:metadata !.*]], metadata !DIExpression()), [[DBG324]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[END:%.*]], label [[LOOP]], [[DBG325:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG321]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG326:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %end, label %loop ; wrong order of successors
end:
ret i32 %x.curr
}
; We should loop while %x.curr.bitmasked is 0, not while it is not 0.
define i32 @n21(i32 %x, i32 %bit) {
; ALL-LABEL: @n21(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG334:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META329:metadata !.*]], metadata !DIExpression()), [[DBG334]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG335:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG336:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META330:metadata !.*]], metadata !DIExpression()), [[DBG336]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG337:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META331:metadata !.*]], metadata !DIExpression()), [[DBG337]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp ne i32 [[X_CURR_BITMASKED]], 0, [[DBG338:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META332:metadata !.*]], metadata !DIExpression()), [[DBG338]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG339:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META333:metadata !.*]], metadata !DIExpression()), [[DBG339]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG340:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG336]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG341:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp ne i32 %x.curr.bitmasked, 0 ; wrong predicate
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; PHI node is not a recurrence
define i32 @n22(i32 %x, i32 %bit) {
; ALL-LABEL: @n22(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG349:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META344:metadata !.*]], metadata !DIExpression()), [[DBG349]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG350:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X:%.*]], [[META345:metadata !.*]], metadata !DIExpression()), [[DBG351:!dbg !.*]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X]], [[BITMASK]], [[DBG352:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META346:metadata !.*]], metadata !DIExpression()), [[DBG352]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG353:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META347:metadata !.*]], metadata !DIExpression()), [[DBG353]]
; ALL-NEXT: [[X_NEXT:%.*]] = shl i32 [[X]], 1, [[DBG354:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META348:metadata !.*]], metadata !DIExpression()), [[DBG354]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG355:!dbg !.*]]
; ALL: end:
; ALL-NEXT: ret i32 [[X]], [[DBG356:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x, %loop ] ; should use %x.next when coming from %loop
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; Masking wrong value
define i32 @n23(i32 %x, i32 %bit) {
; ALL-LABEL: @n23(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG364:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META359:metadata !.*]], metadata !DIExpression()), [[DBG364]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG365:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG366:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META360:metadata !.*]], metadata !DIExpression()), [[DBG366]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X]], [[BITMASK]], [[DBG367:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META361:metadata !.*]], metadata !DIExpression()), [[DBG367]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG368:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META362:metadata !.*]], metadata !DIExpression()), [[DBG368]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG369:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META363:metadata !.*]], metadata !DIExpression()), [[DBG369]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG370:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG366]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG371:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x, %bitmask ; should use %x.curr, not %x
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; Checking wrong value
define i32 @n24(i32 %x, i32 %bit) {
; ALL-LABEL: @n24(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG379:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META374:metadata !.*]], metadata !DIExpression()), [[DBG379]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG380:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG381:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META375:metadata !.*]], metadata !DIExpression()), [[DBG381]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG382:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META376:metadata !.*]], metadata !DIExpression()), [[DBG382]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR]], 0, [[DBG383:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META377:metadata !.*]], metadata !DIExpression()), [[DBG383]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG384:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META378:metadata !.*]], metadata !DIExpression()), [[DBG384]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG385:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG381]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG386:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr, 0 ; should be checking %x.curr.bitmasked
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; Shifting wrong value
define i32 @n25(i32 %x, i32 %bit) {
; ALL-LABEL: @n25(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG394:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META389:metadata !.*]], metadata !DIExpression()), [[DBG394]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG395:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG396:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META390:metadata !.*]], metadata !DIExpression()), [[DBG396]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG397:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META391:metadata !.*]], metadata !DIExpression()), [[DBG397]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG398:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META392:metadata !.*]], metadata !DIExpression()), [[DBG398]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X]], 1, [[DBG399:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META393:metadata !.*]], metadata !DIExpression()), [[DBG399]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG400:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG396]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG401:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x, 1 ; should be shifting %x.curr
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; Bit mask is not a power of 2
define i32 @n26(i32 %x) {
; ALL-LABEL: @n26(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG408:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG409:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META404:metadata !.*]], metadata !DIExpression()), [[DBG409]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 16777215, [[DBG410:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META405:metadata !.*]], metadata !DIExpression()), [[DBG410]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG411:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META406:metadata !.*]], metadata !DIExpression()), [[DBG411]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG412:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META407:metadata !.*]], metadata !DIExpression()), [[DBG412]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG413:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG409]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG414:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, 16777215 ; not a power of 2
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; Bit mask is not a power of 2
define i32 @n27(i32 %x) {
; ALL-LABEL: @n27(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG421:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG422:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META417:metadata !.*]], metadata !DIExpression()), [[DBG422]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 384, [[DBG423:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META418:metadata !.*]], metadata !DIExpression()), [[DBG423]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG424:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META419:metadata !.*]], metadata !DIExpression()), [[DBG424]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG425:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META420:metadata !.*]], metadata !DIExpression()), [[DBG425]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG426:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG422]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG427:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, 384 ; not a power of 2
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; Bit mask is not a power of 2
define i32 @n28(i32 %x) {
; ALL-LABEL: @n28(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG434:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG435:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META430:metadata !.*]], metadata !DIExpression()), [[DBG435]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 32896, [[DBG436:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META431:metadata !.*]], metadata !DIExpression()), [[DBG436]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG437:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META432:metadata !.*]], metadata !DIExpression()), [[DBG437]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG438:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META433:metadata !.*]], metadata !DIExpression()), [[DBG438]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG439:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG435]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG440:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, 32896 ; not a power of 2
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
;-------------------------------------------------------------------------------
; Tests with extra cruft.
; If loop body has any extra instructions we don't want to deal with it.
define i32 @n29(i32 %x, i32 %bit) {
; LZCNT-LABEL: @n29(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG448:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META443:metadata !.*]], metadata !DIExpression()), [[DBG448]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG449:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG449]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG449]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG449]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG449]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG449]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG449]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG449]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG449]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG449]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG450:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG449]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG449]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META444:metadata !.*]], metadata !DIExpression()), [[DBG449]]
; LZCNT-NEXT: call void @external_side_effect(), [[DBG451:!dbg !.*]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG452:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META445:metadata !.*]], metadata !DIExpression()), [[DBG452]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG453:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META446:metadata !.*]], metadata !DIExpression()), [[DBG453]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG454:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META447:metadata !.*]], metadata !DIExpression()), [[DBG454]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG455:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG455]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG455]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG449]]
; LZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG456:!dbg !.*]]
;
; NOLZCNT-LABEL: @n29(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG448:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META443:metadata !.*]], metadata !DIExpression()), [[DBG448]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG449:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG450:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META444:metadata !.*]], metadata !DIExpression()), [[DBG450]]
; NOLZCNT-NEXT: call void @external_side_effect(), [[DBG451:!dbg !.*]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG452:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META445:metadata !.*]], metadata !DIExpression()), [[DBG452]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG453:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META446:metadata !.*]], metadata !DIExpression()), [[DBG453]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG454:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META447:metadata !.*]], metadata !DIExpression()), [[DBG454]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG455:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG450]]
; NOLZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG456:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
call void @external_side_effect() ; not part of idiom.
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
define i32 @n30(i32 %x) {
; LZCNT-LABEL: @n30(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[X_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true), [[DBG462:!dbg !.*]]
; LZCNT-NEXT: [[X_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_NUMLEADINGZEROS]], [[DBG462]]
; LZCNT-NEXT: [[X_LEADINGONEPOS:%.*]] = add i32 [[X_NUMACTIVEBITS]], -1, [[DBG462]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 31, [[X_LEADINGONEPOS]], [[DBG462]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG462]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG462]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG462]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG463:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG462]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG462]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META459:metadata !.*]], metadata !DIExpression()), [[DBG462]]
; LZCNT-NEXT: call void @external_side_effect(), [[DBG464:!dbg !.*]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp sgt i32 [[TMP0]], -1, [[DBG465:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META460:metadata !.*]], metadata !DIExpression()), [[DBG465]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG466:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META461:metadata !.*]], metadata !DIExpression()), [[DBG466]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG467:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG467]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG467]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG462]]
; LZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG468:!dbg !.*]]
;
; NOLZCNT-LABEL: @n30(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG462:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG463:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META459:metadata !.*]], metadata !DIExpression()), [[DBG463]]
; NOLZCNT-NEXT: call void @external_side_effect(), [[DBG464:!dbg !.*]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp sgt i32 [[X_CURR]], -1, [[DBG465:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META460:metadata !.*]], metadata !DIExpression()), [[DBG465]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG466:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META461:metadata !.*]], metadata !DIExpression()), [[DBG466]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG467:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG463]]
; NOLZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG468:!dbg !.*]]
;
entry:
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
call void @external_side_effect() ; not part of idiom.
%x.curr.isbitunset = icmp sgt i32 %x.curr, -1
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; In-loop instructions should not have uses outside of the loop.
define i32 @n31(i32 %x, i32 %bit) {
; LZCNT-LABEL: @n31(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG476:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META471:metadata !.*]], metadata !DIExpression()), [[DBG476]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG477:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG477]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG477]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG477]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG477]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG477]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG477]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG477]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG477]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG477]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG478:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG477]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG477]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META472:metadata !.*]], metadata !DIExpression()), [[DBG477]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG479:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META473:metadata !.*]], metadata !DIExpression()), [[DBG479]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG480:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META474:metadata !.*]], metadata !DIExpression()), [[DBG480]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG481:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META475:metadata !.*]], metadata !DIExpression()), [[DBG481]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG482:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG482]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG482]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG477]]
; LZCNT-NEXT: [[X_CURR_BITMASKED_LCSSA:%.*]] = phi i32 [ [[X_CURR_BITMASKED]], [[LOOP]] ], [[DBG479]]
; LZCNT-NEXT: call void @use32(i32 [[X_CURR_BITMASKED_LCSSA]]), [[DBG483:!dbg !.*]]
; LZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG484:!dbg !.*]]
;
; NOLZCNT-LABEL: @n31(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG476:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META471:metadata !.*]], metadata !DIExpression()), [[DBG476]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG477:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG478:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META472:metadata !.*]], metadata !DIExpression()), [[DBG478]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG479:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META473:metadata !.*]], metadata !DIExpression()), [[DBG479]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG480:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META474:metadata !.*]], metadata !DIExpression()), [[DBG480]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG481:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META475:metadata !.*]], metadata !DIExpression()), [[DBG481]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG482:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG478]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED_LCSSA:%.*]] = phi i32 [ [[X_CURR_BITMASKED]], [[LOOP]] ], [[DBG479]]
; NOLZCNT-NEXT: call void @use32(i32 [[X_CURR_BITMASKED_LCSSA]]), [[DBG483:!dbg !.*]]
; NOLZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG484:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
call void @use32(i32 %x.curr.bitmasked)
ret i32 %x.curr
}
define i32 @n32(i32 %x, i32 %bit) {
; LZCNT-LABEL: @n32(
; LZCNT-NEXT: entry:
; LZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG492:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META487:metadata !.*]], metadata !DIExpression()), [[DBG492]]
; LZCNT-NEXT: [[BIT_LOWBITMASK:%.*]] = add i32 [[BITMASK]], -1, [[DBG493:!dbg !.*]]
; LZCNT-NEXT: [[BIT_MASK:%.*]] = or i32 [[BIT_LOWBITMASK]], [[BITMASK]], [[DBG493]]
; LZCNT-NEXT: [[X_MASKED:%.*]] = and i32 [[X:%.*]], [[BIT_MASK]], [[DBG493]]
; LZCNT-NEXT: [[X_MASKED_NUMLEADINGZEROS:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X_MASKED]], i1 true), [[DBG493]]
; LZCNT-NEXT: [[X_MASKED_NUMACTIVEBITS:%.*]] = sub i32 32, [[X_MASKED_NUMLEADINGZEROS]], [[DBG493]]
; LZCNT-NEXT: [[X_MASKED_LEADINGONEPOS:%.*]] = add i32 [[X_MASKED_NUMACTIVEBITS]], -1, [[DBG493]]
; LZCNT-NEXT: [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub i32 [[BIT]], [[X_MASKED_LEADINGONEPOS]], [[DBG493]]
; LZCNT-NEXT: [[LOOP_TRIPCOUNT:%.*]] = add nuw i32 [[LOOP_BACKEDGETAKENCOUNT]], 1, [[DBG493]]
; LZCNT-NEXT: [[X_CURR:%.*]] = shl i32 [[X]], [[LOOP_BACKEDGETAKENCOUNT]], [[DBG493]]
; LZCNT-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG493]]
; LZCNT-NEXT: br label [[LOOP:%.*]], [[DBG494:!dbg !.*]]
; LZCNT: loop:
; LZCNT-NEXT: [[LOOP_IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ], [[DBG493]]
; LZCNT-NEXT: [[TMP0:%.*]] = phi i32 [ [[X]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP]] ], [[DBG493]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP0]], [[META488:metadata !.*]], metadata !DIExpression()), [[DBG493]]
; LZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[TMP0]], [[BITMASK]], [[DBG495:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META489:metadata !.*]], metadata !DIExpression()), [[DBG495]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG496:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META490:metadata !.*]], metadata !DIExpression()), [[DBG496]]
; LZCNT-NEXT: [[TMP1]] = shl i32 [[TMP0]], 1, [[DBG497:!dbg !.*]]
; LZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[TMP1]], [[META491:metadata !.*]], metadata !DIExpression()), [[DBG497]]
; LZCNT-NEXT: [[LOOP_IV_NEXT]] = add nuw i32 [[LOOP_IV]], 1, [[DBG498:!dbg !.*]]
; LZCNT-NEXT: [[LOOP_IVCHECK:%.*]] = icmp eq i32 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]], [[DBG498]]
; LZCNT-NEXT: br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]], [[DBG498]]
; LZCNT: end:
; LZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG493]]
; LZCNT-NEXT: [[X_CURR_ISBITUNSET_LCSSA:%.*]] = phi i1 [ [[X_CURR_ISBITUNSET]], [[LOOP]] ], [[DBG496]]
; LZCNT-NEXT: call void @use1(i1 [[X_CURR_ISBITUNSET_LCSSA]]), [[DBG499:!dbg !.*]]
; LZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG500:!dbg !.*]]
;
; NOLZCNT-LABEL: @n32(
; NOLZCNT-NEXT: entry:
; NOLZCNT-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG492:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META487:metadata !.*]], metadata !DIExpression()), [[DBG492]]
; NOLZCNT-NEXT: br label [[LOOP:%.*]], [[DBG493:!dbg !.*]]
; NOLZCNT: loop:
; NOLZCNT-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG494:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META488:metadata !.*]], metadata !DIExpression()), [[DBG494]]
; NOLZCNT-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG495:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META489:metadata !.*]], metadata !DIExpression()), [[DBG495]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG496:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META490:metadata !.*]], metadata !DIExpression()), [[DBG496]]
; NOLZCNT-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG497:!dbg !.*]]
; NOLZCNT-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META491:metadata !.*]], metadata !DIExpression()), [[DBG497]]
; NOLZCNT-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG498:!dbg !.*]]
; NOLZCNT: end:
; NOLZCNT-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG494]]
; NOLZCNT-NEXT: [[X_CURR_ISBITUNSET_LCSSA:%.*]] = phi i1 [ [[X_CURR_ISBITUNSET]], [[LOOP]] ], [[DBG496]]
; NOLZCNT-NEXT: call void @use1(i1 [[X_CURR_ISBITUNSET_LCSSA]]), [[DBG499:!dbg !.*]]
; NOLZCNT-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG500:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
call void @use1(i1 %x.curr.isbitunset)
ret i32 %x.curr
}
; %x.curr is not a PHI node
define i32 @n33(i32 %x, i32 %bit, i32 %x.curr) {
; ALL-LABEL: @n33(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG507:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META503:metadata !.*]], metadata !DIExpression()), [[DBG507]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG508:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR:%.*]], [[BITMASK]], [[DBG509:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META504:metadata !.*]], metadata !DIExpression()), [[DBG509]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG510:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META505:metadata !.*]], metadata !DIExpression()), [[DBG510]]
; ALL-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG511:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META506:metadata !.*]], metadata !DIExpression()), [[DBG511]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG512:!dbg !.*]]
; ALL: end:
; ALL-NEXT: ret i32 [[X_CURR]], [[DBG513:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br label %loop
loop:
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}
; %x.curr is a PHI node in a wrong block
define i32 @n34(i32 %bit, i1 %c, i32 %x0, i32 %x1) {
; ALL-LABEL: @n34(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG521:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META516:metadata !.*]], metadata !DIExpression()), [[DBG521]]
; ALL-NEXT: br i1 [[C:%.*]], label [[BB0:%.*]], label [[BB1:%.*]], [[DBG522:!dbg !.*]]
; ALL: bb0:
; ALL-NEXT: br label [[MERGE:%.*]], [[DBG523:!dbg !.*]]
; ALL: bb1:
; ALL-NEXT: br label [[MERGE]], [[DBG524:!dbg !.*]]
; ALL: merge:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X0:%.*]], [[BB0]] ], [ [[X1:%.*]], [[BB1]] ], [[DBG525:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META517:metadata !.*]], metadata !DIExpression()), [[DBG525]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG526:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG527:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META518:metadata !.*]], metadata !DIExpression()), [[DBG527]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG528:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META519:metadata !.*]], metadata !DIExpression()), [[DBG528]]
; ALL-NEXT: [[X_NEXT:%.*]] = shl i32 [[X_CURR]], 1, [[DBG529:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META520:metadata !.*]], metadata !DIExpression()), [[DBG529]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG530:!dbg !.*]]
; ALL: end:
; ALL-NEXT: ret i32 [[X_CURR]], [[DBG531:!dbg !.*]]
;
entry:
%bitmask = shl i32 1, %bit
br i1 %c, label %bb0, label %bb1
bb0:
br label %merge
bb1:
br label %merge
merge:
%x.curr = phi i32 [ %x0, %bb0 ], [ %x1, %bb1 ]
br label %loop
loop:
%x.curr.bitmasked = and i32 %x.curr, %bitmask
%x.curr.isbitunset = icmp eq i32 %x.curr.bitmasked, 0
%x.next = shl i32 %x.curr, 1
br i1 %x.curr.isbitunset, label %loop, label %end
end:
ret i32 %x.curr
}