|
2 | 2 | ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
3 | 3 | declare void @use8(i8)
|
4 | 4 | declare i64 @llvm.vscale.i64()
|
| 5 | +declare i32 @llvm.vscale.i32() |
5 | 6 |
|
6 | 7 | define i8 @srem_non_matching(i8 %X, i8 %Y) {
|
7 | 8 | ; CHECK-LABEL: @srem_non_matching(
|
@@ -913,3 +914,32 @@ define i64 @and_add_shl_vscale_not_power2() vscale_range(1,16) {
|
913 | 914 | %rem = and i64 3072, %add
|
914 | 915 | ret i64 %rem
|
915 | 916 | }
|
| 917 | + |
| 918 | +; Allow for INT_MIN, https://alive2.llvm.org/ce/z/yZ_I2a |
| 919 | +define i32 @and_add_shl_vscale_not_power2_negative() vscale_range(1,16) { |
| 920 | +; CHECK-LABEL: @and_add_shl_vscale_not_power2_negative( |
| 921 | +; CHECK-NEXT: ret i32 0 |
| 922 | +; |
| 923 | + %vscale = call i32 @llvm.vscale.i32() |
| 924 | + %shift = shl nuw nsw i32 %vscale, 6 |
| 925 | + %add = add i32 %shift, -1 |
| 926 | + %rem = and i32 -2147483648, %add |
| 927 | + ret i32 %rem |
| 928 | +} |
| 929 | + |
| 930 | +; Negative test: the %sign may be 0, https://alive2.llvm.org/ce/z/WU_j4a |
| 931 | +define i32 @and_add_and (i32 %x) { |
| 932 | +; CHECK-LABEL: @and_add_and( |
| 933 | +; CHECK-NEXT: [[X1:%.*]] = lshr i32 [[X:%.*]], 7 |
| 934 | +; CHECK-NEXT: [[SIGN:%.*]] = and i32 [[X1]], 1 |
| 935 | +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SIGN]], -1 |
| 936 | +; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], -2147483648 |
| 937 | +; CHECK-NEXT: ret i32 [[AND]] |
| 938 | +; |
| 939 | + %x1 = lshr i32 %x, 7 |
| 940 | + %sign = and i32 %x1, 1 ; %sign = (%x >> 7) & 1 |
| 941 | + %add = add i32 %sign, -1 |
| 942 | + %and = and i32 %add, 2147483648 |
| 943 | + ret i32 %and |
| 944 | +} |
| 945 | + |
0 commit comments