blob: 65c73095533349beff0bf29c9a620a09abdc73b4 [file] [log] [blame] [edit]
; 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-prefix=ALL %s
; RUN: opt -debugify -loop-idiom -mtriple=x86_64 -mcpu=corei7 < %s -S | FileCheck --check-prefix=ALL %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) {
; ALL-LABEL: @p0_i32(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG16:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META9:metadata !.*]], metadata !DIExpression()), [[DBG16]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG17:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG18:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META11:metadata !.*]], metadata !DIExpression()), [[DBG18]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG19:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META12:metadata !.*]], metadata !DIExpression()), [[DBG19]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG20:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META13:metadata !.*]], metadata !DIExpression()), [[DBG20]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG21:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META15:metadata !.*]], metadata !DIExpression()), [[DBG21]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG22:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG18]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META11]], metadata !DIExpression()), [[DBG18]]
; ALL-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) {
; ALL-LABEL: @p1_i16(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i16 1, [[BIT:%.*]], [[DBG32:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i16 [[BITMASK]], [[META26:metadata !.*]], metadata !DIExpression()), [[DBG32]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG33:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i16 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG34:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i16 [[X_CURR]], [[META28:metadata !.*]], metadata !DIExpression()), [[DBG34]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i16 [[X_CURR]], [[BITMASK]], [[DBG35:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i16 [[X_CURR_BITMASKED]], [[META29:metadata !.*]], metadata !DIExpression()), [[DBG35]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i16 [[X_CURR_BITMASKED]], 0, [[DBG36:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META30:metadata !.*]], metadata !DIExpression()), [[DBG36]]
; ALL-NEXT: [[X_NEXT]] = shl i16 [[X_CURR]], 1, [[DBG37:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i16 [[X_NEXT]], [[META31:metadata !.*]], metadata !DIExpression()), [[DBG37]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG38:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i16 [ [[X_CURR]], [[LOOP]] ], [[DBG34]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i16 [[X_CURR_LCSSA]], [[META28]], metadata !DIExpression()), [[DBG34]]
; ALL-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
}
define i32 @p2_constant_mask_24thbit(i32 %x) {
; ALL-LABEL: @p2_constant_mask_24thbit(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG46:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG47:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META42:metadata !.*]], metadata !DIExpression()), [[DBG47]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 16777216, [[DBG48:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META43:metadata !.*]], metadata !DIExpression()), [[DBG48]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG49:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META44:metadata !.*]], metadata !DIExpression()), [[DBG49]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG50:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META45:metadata !.*]], metadata !DIExpression()), [[DBG50]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG51:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG47]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META42]], metadata !DIExpression()), [[DBG47]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG52:!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:
ret i32 %x.curr
}
define i32 @p3_constant_mask_15thbit(i32 %x) {
; ALL-LABEL: @p3_constant_mask_15thbit(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG59:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG60:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META55:metadata !.*]], metadata !DIExpression()), [[DBG60]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 32768, [[DBG61:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META56:metadata !.*]], metadata !DIExpression()), [[DBG61]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG62:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META57:metadata !.*]], metadata !DIExpression()), [[DBG62]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG63:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META58:metadata !.*]], metadata !DIExpression()), [[DBG63]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG64:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG60]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META55]], metadata !DIExpression()), [[DBG60]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG65:!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:
ret i32 %x.curr
}
; We don't particularly care whether %x.curr or %x.curr will live-out.
define i32 @p4_different_liveout(i32 %x, i32 %bit) {
; ALL-LABEL: @p4_different_liveout(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG73:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META68:metadata !.*]], metadata !DIExpression()), [[DBG73]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG74:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG75:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META69:metadata !.*]], metadata !DIExpression()), [[DBG75]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG76:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META70:metadata !.*]], metadata !DIExpression()), [[DBG76]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG77:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META71:metadata !.*]], metadata !DIExpression()), [[DBG77]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG78:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META72:metadata !.*]], metadata !DIExpression()), [[DBG78]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG79:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG78]]
; ALL-NEXT: ret i32 [[X_NEXT_LCSSA]], [[DBG80:!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 being live-out is fine.
define void @p5_both_liveout(i32 %x, i32 %bit, i32* %p0, i32* %p1) {
; ALL-LABEL: @p5_both_liveout(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG88:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META83:metadata !.*]], metadata !DIExpression()), [[DBG88]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG89:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG90:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META84:metadata !.*]], metadata !DIExpression()), [[DBG90]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG91:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META85:metadata !.*]], metadata !DIExpression()), [[DBG91]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG92:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META86:metadata !.*]], metadata !DIExpression()), [[DBG92]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG93:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META87:metadata !.*]], metadata !DIExpression()), [[DBG93]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG94:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG90]]
; ALL-NEXT: [[X_NEXT_LCSSA:%.*]] = phi i32 [ [[X_NEXT]], [[LOOP]] ], [[DBG93]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META84]], metadata !DIExpression()), [[DBG90]]
; ALL-NEXT: store i32 [[X_CURR_LCSSA]], i32* [[P0:%.*]], align 4, [[DBG95:!dbg !.*]]
; ALL-NEXT: store i32 [[X_NEXT_LCSSA]], i32* [[P1:%.*]], align 4, [[DBG96:!dbg !.*]]
; ALL-NEXT: ret void, [[DBG97:!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:
store i32 %x.curr, i32* %p0
store i32 %x.next, i32* %p1
ret void
}
define i32 @p6_constant_mask_signbit_noncanonical(i32 %x) {
; ALL-LABEL: @p6_constant_mask_signbit_noncanonical(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG104:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG105:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META100:metadata !.*]], metadata !DIExpression()), [[DBG105]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], -2147483648, [[DBG106:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META101:metadata !.*]], metadata !DIExpression()), [[DBG106]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG107:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META102:metadata !.*]], metadata !DIExpression()), [[DBG107]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG108:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META103:metadata !.*]], metadata !DIExpression()), [[DBG108]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG109:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG105]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META100]], metadata !DIExpression()), [[DBG105]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG110:!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:
ret i32 %x.curr
}
define i32 @p7_constant_mask_signbit_canonical(i32 %x) {
; ALL-LABEL: @p7_constant_mask_signbit_canonical(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG116:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG117:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META113:metadata !.*]], metadata !DIExpression()), [[DBG117]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp sgt i32 [[X_CURR]], -1, [[DBG118:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META114:metadata !.*]], metadata !DIExpression()), [[DBG118]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG119:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META115:metadata !.*]], metadata !DIExpression()), [[DBG119]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG120:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG117]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META113]], metadata !DIExpression()), [[DBG117]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG121:!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:
ret i32 %x.curr
}
; Check that loop backedge's cmp-br order is correctly handled
define i32 @p8(i32 %x, i32 %bit) {
; ALL-LABEL: @p8(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG129:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META124:metadata !.*]], metadata !DIExpression()), [[DBG129]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG130:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG131:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META125:metadata !.*]], metadata !DIExpression()), [[DBG131]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG132:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META126:metadata !.*]], metadata !DIExpression()), [[DBG132]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp ne i32 [[X_CURR_BITMASKED]], 0, [[DBG133:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META127:metadata !.*]], metadata !DIExpression()), [[DBG133]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG134:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META128:metadata !.*]], metadata !DIExpression()), [[DBG134]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[END:%.*]], label [[LOOP]], [[DBG135:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG131]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META125]], metadata !DIExpression()), [[DBG131]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG136:!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 @p9(i32 %x, i32 %bit) {
; ALL-LABEL: @p9(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG144:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META139:metadata !.*]], metadata !DIExpression()), [[DBG144]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG145:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG146:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META140:metadata !.*]], metadata !DIExpression()), [[DBG146]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[BITMASK]], [[X_CURR]], [[DBG147:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META141:metadata !.*]], metadata !DIExpression()), [[DBG147]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG148:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META142:metadata !.*]], metadata !DIExpression()), [[DBG148]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG149:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META143:metadata !.*]], metadata !DIExpression()), [[DBG149]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG150:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG146]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META140]], metadata !DIExpression()), [[DBG146]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG151:!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 @p10(i32 %x, i32 %bit) {
; ALL-LABEL: @p10(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG159:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META154:metadata !.*]], metadata !DIExpression()), [[DBG159]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG160:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X_NEXT:%.*]], [[LOOP]] ], [ [[X:%.*]], [[ENTRY:%.*]] ], [[DBG161:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META155:metadata !.*]], metadata !DIExpression()), [[DBG161]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG162:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META156:metadata !.*]], metadata !DIExpression()), [[DBG162]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG163:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META157:metadata !.*]], metadata !DIExpression()), [[DBG163]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG164:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META158:metadata !.*]], metadata !DIExpression()), [[DBG164]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG165:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG161]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META155]], metadata !DIExpression()), [[DBG161]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG166:!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 @p11(i32 %x) {
; ALL-LABEL: @p11(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG172:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG173:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META169:metadata !.*]], metadata !DIExpression()), [[DBG173]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp slt i32 [[X_CURR]], 0, [[DBG174:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META170:metadata !.*]], metadata !DIExpression()), [[DBG174]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG175:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META171:metadata !.*]], metadata !DIExpression()), [[DBG175]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[END:%.*]], label [[LOOP]], [[DBG176:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG173]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META169]], metadata !DIExpression()), [[DBG173]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG177:!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 @n12(i32 %x, i32 %bit) {
; ALL-LABEL: @n12(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG185:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG186:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META180:metadata !.*]], metadata !DIExpression()), [[DBG186]]
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG187:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META181:metadata !.*]], metadata !DIExpression()), [[DBG187]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG188:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META182:metadata !.*]], metadata !DIExpression()), [[DBG188]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG189:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META183:metadata !.*]], metadata !DIExpression()), [[DBG189]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG190:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META184:metadata !.*]], metadata !DIExpression()), [[DBG190]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG191:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG186]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META180]], metadata !DIExpression()), [[DBG186]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG192:!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 @n13(i32 %x, i32 %bit) {
; ALL-LABEL: @n13(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG200:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG201:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META195:metadata !.*]], metadata !DIExpression()), [[DBG201]]
; ALL-NEXT: [[BITMASK:%.*]] = call i32 @gen32(), [[DBG202:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META196:metadata !.*]], metadata !DIExpression()), [[DBG202]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG203:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META197:metadata !.*]], metadata !DIExpression()), [[DBG203]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG204:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META198:metadata !.*]], metadata !DIExpression()), [[DBG204]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG205:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META199:metadata !.*]], metadata !DIExpression()), [[DBG205]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG206:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG201]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META195]], metadata !DIExpression()), [[DBG201]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG207:!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 @n14(i32 %x, i32 %bit) {
; ALL-LABEL: @n14(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 2, [[BIT:%.*]], [[DBG215:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META210:metadata !.*]], metadata !DIExpression()), [[DBG215]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG216:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG217:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META211:metadata !.*]], metadata !DIExpression()), [[DBG217]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG218:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META212:metadata !.*]], metadata !DIExpression()), [[DBG218]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG219:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META213:metadata !.*]], metadata !DIExpression()), [[DBG219]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG220:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META214:metadata !.*]], metadata !DIExpression()), [[DBG220]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG221:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG217]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META211]], metadata !DIExpression()), [[DBG217]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG222:!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 @n15(i32 %x, i32 %bit) {
; ALL-LABEL: @n15(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG230:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META225:metadata !.*]], metadata !DIExpression()), [[DBG230]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG231:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG232:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META226:metadata !.*]], metadata !DIExpression()), [[DBG232]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG233:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META227:metadata !.*]], metadata !DIExpression()), [[DBG233]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG234:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META228:metadata !.*]], metadata !DIExpression()), [[DBG234]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 2, [[DBG235:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META229:metadata !.*]], metadata !DIExpression()), [[DBG235]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG236:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG232]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META226]], metadata !DIExpression()), [[DBG232]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG237:!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 @n16(i32 %x, i32 %bit) {
; ALL-LABEL: @n16(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG245:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META240:metadata !.*]], metadata !DIExpression()), [[DBG245]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG246:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG247:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META241:metadata !.*]], metadata !DIExpression()), [[DBG247]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG248:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META242:metadata !.*]], metadata !DIExpression()), [[DBG248]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp ne i32 [[X_CURR_BITMASKED]], [[BITMASK]], [[DBG249:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META243:metadata !.*]], metadata !DIExpression()), [[DBG249]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG250:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META244:metadata !.*]], metadata !DIExpression()), [[DBG250]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG251:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG247]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META241]], metadata !DIExpression()), [[DBG247]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG252:!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 @n17(i32 %x, i32 %bit) {
; ALL-LABEL: @n17(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG260:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META255:metadata !.*]], metadata !DIExpression()), [[DBG260]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG261:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG262:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META256:metadata !.*]], metadata !DIExpression()), [[DBG262]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG263:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META257:metadata !.*]], metadata !DIExpression()), [[DBG263]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG264:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META258:metadata !.*]], metadata !DIExpression()), [[DBG264]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG265:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META259:metadata !.*]], metadata !DIExpression()), [[DBG265]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[END:%.*]], label [[LOOP]], [[DBG266:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG262]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META256]], metadata !DIExpression()), [[DBG262]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG267:!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 @n18(i32 %x, i32 %bit) {
; ALL-LABEL: @n18(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG275:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META270:metadata !.*]], metadata !DIExpression()), [[DBG275]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG276:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG277:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META271:metadata !.*]], metadata !DIExpression()), [[DBG277]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG278:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META272:metadata !.*]], metadata !DIExpression()), [[DBG278]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp ne i32 [[X_CURR_BITMASKED]], 0, [[DBG279:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META273:metadata !.*]], metadata !DIExpression()), [[DBG279]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG280:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META274:metadata !.*]], metadata !DIExpression()), [[DBG280]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG281:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG277]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META271]], metadata !DIExpression()), [[DBG277]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG282:!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 @n19(i32 %x, i32 %bit) {
; ALL-LABEL: @n19(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG290:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META285:metadata !.*]], metadata !DIExpression()), [[DBG290]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG291:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X:%.*]], [[META286:metadata !.*]], metadata !DIExpression()), [[DBG292:!dbg !.*]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X]], [[BITMASK]], [[DBG293:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META287:metadata !.*]], metadata !DIExpression()), [[DBG293]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG294:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META288:metadata !.*]], metadata !DIExpression()), [[DBG294]]
; ALL-NEXT: [[X_NEXT:%.*]] = shl i32 [[X]], 1, [[DBG295:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META289:metadata !.*]], metadata !DIExpression()), [[DBG295]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG296:!dbg !.*]]
; ALL: end:
; ALL-NEXT: ret i32 [[X]], [[DBG297:!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 @n20(i32 %x, i32 %bit) {
; ALL-LABEL: @n20(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG305:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META300:metadata !.*]], metadata !DIExpression()), [[DBG305]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG306:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG307:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META301:metadata !.*]], metadata !DIExpression()), [[DBG307]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X]], [[BITMASK]], [[DBG308:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META302:metadata !.*]], metadata !DIExpression()), [[DBG308]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG309:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META303:metadata !.*]], metadata !DIExpression()), [[DBG309]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG310:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META304:metadata !.*]], metadata !DIExpression()), [[DBG310]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG311:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG307]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META301]], metadata !DIExpression()), [[DBG307]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG312:!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 @n21(i32 %x, i32 %bit) {
; ALL-LABEL: @n21(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG320:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META315:metadata !.*]], metadata !DIExpression()), [[DBG320]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG321:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG322:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META316:metadata !.*]], metadata !DIExpression()), [[DBG322]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG323:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META317:metadata !.*]], metadata !DIExpression()), [[DBG323]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR]], 0, [[DBG324:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META318:metadata !.*]], metadata !DIExpression()), [[DBG324]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG325:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META319:metadata !.*]], metadata !DIExpression()), [[DBG325]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG326:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG322]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META316]], metadata !DIExpression()), [[DBG322]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG327:!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 @n22(i32 %x, i32 %bit) {
; ALL-LABEL: @n22(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG335:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META330:metadata !.*]], metadata !DIExpression()), [[DBG335]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG336:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG337:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META331:metadata !.*]], metadata !DIExpression()), [[DBG337]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG338:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META332:metadata !.*]], metadata !DIExpression()), [[DBG338]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG339:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META333:metadata !.*]], metadata !DIExpression()), [[DBG339]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X]], 1, [[DBG340:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META334:metadata !.*]], metadata !DIExpression()), [[DBG340]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG341:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG337]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META331]], metadata !DIExpression()), [[DBG337]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG342:!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 @n23(i32 %x) {
; ALL-LABEL: @n23(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG349:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG350:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META345:metadata !.*]], metadata !DIExpression()), [[DBG350]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 16777215, [[DBG351:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META346:metadata !.*]], metadata !DIExpression()), [[DBG351]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG352:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META347:metadata !.*]], metadata !DIExpression()), [[DBG352]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG353:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META348:metadata !.*]], metadata !DIExpression()), [[DBG353]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG354:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG350]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META345]], metadata !DIExpression()), [[DBG350]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG355:!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 @n24(i32 %x) {
; ALL-LABEL: @n24(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG362:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG363:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META358:metadata !.*]], metadata !DIExpression()), [[DBG363]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 384, [[DBG364:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META359:metadata !.*]], metadata !DIExpression()), [[DBG364]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG365:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META360:metadata !.*]], metadata !DIExpression()), [[DBG365]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG366:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META361:metadata !.*]], metadata !DIExpression()), [[DBG366]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG367:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG363]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META358]], metadata !DIExpression()), [[DBG363]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG368:!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 @n25(i32 %x) {
; ALL-LABEL: @n25(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG375:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG376:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META371:metadata !.*]], metadata !DIExpression()), [[DBG376]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], 32896, [[DBG377:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META372:metadata !.*]], metadata !DIExpression()), [[DBG377]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG378:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META373:metadata !.*]], metadata !DIExpression()), [[DBG378]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG379:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META374:metadata !.*]], metadata !DIExpression()), [[DBG379]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG380:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG376]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META371]], metadata !DIExpression()), [[DBG376]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG381:!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 @n26(i32 %x, i32 %bit) {
; ALL-LABEL: @n26(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG389:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META384:metadata !.*]], metadata !DIExpression()), [[DBG389]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG390:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG391:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META385:metadata !.*]], metadata !DIExpression()), [[DBG391]]
; ALL-NEXT: call void @external_side_effect(), [[DBG392:!dbg !.*]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG393:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META386:metadata !.*]], metadata !DIExpression()), [[DBG393]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG394:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META387:metadata !.*]], metadata !DIExpression()), [[DBG394]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG395:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META388:metadata !.*]], metadata !DIExpression()), [[DBG395]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG396:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG391]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META385]], metadata !DIExpression()), [[DBG391]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG397:!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 @n27(i32 %x) {
; ALL-LABEL: @n27(
; ALL-NEXT: entry:
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG403:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG404:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META400:metadata !.*]], metadata !DIExpression()), [[DBG404]]
; ALL-NEXT: call void @external_side_effect(), [[DBG405:!dbg !.*]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp sgt i32 [[X_CURR]], -1, [[DBG406:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META401:metadata !.*]], metadata !DIExpression()), [[DBG406]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG407:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META402:metadata !.*]], metadata !DIExpression()), [[DBG407]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG408:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG404]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META400]], metadata !DIExpression()), [[DBG404]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG409:!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 @n28(i32 %x, i32 %bit) {
; ALL-LABEL: @n28(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG417:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META412:metadata !.*]], metadata !DIExpression()), [[DBG417]]
; ALL-NEXT: br label [[LOOP:%.*]], [[DBG418:!dbg !.*]]
; ALL: loop:
; ALL-NEXT: [[X_CURR:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP]] ], [[DBG419:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR]], [[META413:metadata !.*]], metadata !DIExpression()), [[DBG419]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG420:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META414:metadata !.*]], metadata !DIExpression()), [[DBG420]]
; ALL-NEXT: [[X_CURR_ISBITUNSET:%.*]] = icmp eq i32 [[X_CURR_BITMASKED]], 0, [[DBG421:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i1 [[X_CURR_ISBITUNSET]], [[META415:metadata !.*]], metadata !DIExpression()), [[DBG421]]
; ALL-NEXT: [[X_NEXT]] = shl i32 [[X_CURR]], 1, [[DBG422:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_NEXT]], [[META416:metadata !.*]], metadata !DIExpression()), [[DBG422]]
; ALL-NEXT: br i1 [[X_CURR_ISBITUNSET]], label [[LOOP]], label [[END:%.*]], [[DBG423:!dbg !.*]]
; ALL: end:
; ALL-NEXT: [[X_CURR_LCSSA:%.*]] = phi i32 [ [[X_CURR]], [[LOOP]] ], [[DBG419]]
; ALL-NEXT: [[X_CURR_BITMASKED_LCSSA:%.*]] = phi i32 [ [[X_CURR_BITMASKED]], [[LOOP]] ], [[DBG420]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META413]], metadata !DIExpression()), [[DBG419]]
; ALL-NEXT: call void @use32(i32 [[X_CURR_BITMASKED_LCSSA]]), [[DBG424:!dbg !.*]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG425:!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 @n29(i32 %x, i32 %bit) {
; ALL-LABEL: @n29(
; ALL-NEXT: entry:
; ALL-NEXT: [[BITMASK:%.*]] = shl i32 1, [[BIT:%.*]], [[DBG433:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[BITMASK]], [[META428:metadata !.*]], metadata !DIExpression()), [[DBG433]]
; 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]], [[META429:metadata !.*]], metadata !DIExpression()), [[DBG435]]
; ALL-NEXT: [[X_CURR_BITMASKED:%.*]] = and i32 [[X_CURR]], [[BITMASK]], [[DBG436:!dbg !.*]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_BITMASKED]], [[META430: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]], [[META431: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]], [[META432: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: [[X_CURR_ISBITUNSET_LCSSA:%.*]] = phi i1 [ [[X_CURR_ISBITUNSET]], [[LOOP]] ], [[DBG437]]
; ALL-NEXT: call void @llvm.dbg.value(metadata i32 [[X_CURR_LCSSA]], [[META429]], metadata !DIExpression()), [[DBG435]]
; ALL-NEXT: call void @use1(i1 [[X_CURR_ISBITUNSET_LCSSA]]), [[DBG440:!dbg !.*]]
; ALL-NEXT: ret i32 [[X_CURR_LCSSA]], [[DBG441:!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
}