diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll index bc9bd9262ccdf2..9311f68e808d1b 100644 --- a/llvm/test/Transforms/InstCombine/lshr.ll +++ b/llvm/test/Transforms/InstCombine/lshr.ll @@ -325,3 +325,60 @@ define i32 @mul_splat_fold_no_nuw(i32 %x) { %t = lshr i32 %m, 16 ret i32 %t } + +define i32 @negative_and_odd(i32 %x) { +; CHECK-LABEL: @negative_and_odd( +; CHECK-NEXT: [[S:%.*]] = srem i32 [[X:%.*]], 2 +; CHECK-NEXT: [[R:%.*]] = lshr i32 [[S]], 31 +; CHECK-NEXT: ret i32 [[R]] +; + %s = srem i32 %x, 2 + %r = lshr i32 %s, 31 + ret i32 %r +} + +define <2 x i7> @negative_and_odd_vec(<2 x i7> %x) { +; CHECK-LABEL: @negative_and_odd_vec( +; CHECK-NEXT: [[S:%.*]] = srem <2 x i7> [[X:%.*]], +; CHECK-NEXT: [[R:%.*]] = lshr <2 x i7> [[S]], +; CHECK-NEXT: ret <2 x i7> [[R]] +; + %s = srem <2 x i7> %x, + %r = lshr <2 x i7> %s, + ret <2 x i7> %r +} + +define i32 @negative_and_odd_uses(i32 %x, i32* %p) { +; CHECK-LABEL: @negative_and_odd_uses( +; CHECK-NEXT: [[S:%.*]] = srem i32 [[X:%.*]], 2 +; CHECK-NEXT: store i32 [[S]], i32* [[P:%.*]], align 4 +; CHECK-NEXT: [[R:%.*]] = lshr i32 [[S]], 31 +; CHECK-NEXT: ret i32 [[R]] +; + %s = srem i32 %x, 2 + store i32 %s, i32* %p + %r = lshr i32 %s, 31 + ret i32 %r +} + +define i32 @srem3(i32 %x) { +; CHECK-LABEL: @srem3( +; CHECK-NEXT: [[S:%.*]] = srem i32 [[X:%.*]], 3 +; CHECK-NEXT: [[R:%.*]] = lshr i32 [[S]], 31 +; CHECK-NEXT: ret i32 [[R]] +; + %s = srem i32 %x, 3 + %r = lshr i32 %s, 31 + ret i32 %r +} + +define i32 @srem2_lshr30(i32 %x) { +; CHECK-LABEL: @srem2_lshr30( +; CHECK-NEXT: [[S:%.*]] = srem i32 [[X:%.*]], 2 +; CHECK-NEXT: [[R:%.*]] = lshr i32 [[S]], 30 +; CHECK-NEXT: ret i32 [[R]] +; + %s = srem i32 %x, 2 + %r = lshr i32 %s, 30 + ret i32 %r +} diff --git a/llvm/test/Transforms/InstCombine/rem.ll b/llvm/test/Transforms/InstCombine/rem.ll index 8f0172e952121f..2a75984b223144 100644 --- a/llvm/test/Transforms/InstCombine/rem.ll +++ b/llvm/test/Transforms/InstCombine/rem.ll @@ -738,6 +738,28 @@ define i1 @test28(i32 %A) { ret i1 %C } +define i1 @positive_and_odd(i32 %A) { +; CHECK-LABEL: @positive_and_odd( +; CHECK-NEXT: [[B:%.*]] = srem i32 [[A:%.*]], 2 +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[B]], 1 +; CHECK-NEXT: ret i1 [[C]] +; + %B = srem i32 %A, 2 + %C = icmp eq i32 %B, 1 + ret i1 %C +} + +define i1 @negative_and_odd(i32 %A) { +; CHECK-LABEL: @negative_and_odd( +; CHECK-NEXT: [[B:%.*]] = srem i32 [[A:%.*]], 2 +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[B]], -1 +; CHECK-NEXT: ret i1 [[C]] +; + %B = srem i32 %A, 2 + %C = icmp eq i32 %B, -1 + ret i1 %C +} + ; FP division-by-zero is not UB. define double @PR34870(i1 %cond, double %x, double %y) {