[RISCV] Remove RV64I SLLW/SRLW/SRAW patterns and add new test cases
As noted by Eli Friedman <https://reviews.llvm.org/D52977?id=168629#1315291>,
the RV64I shift patterns for SLLW/SRLW/SRAW make some incorrect assumptions.
SRAW assumed that (sext_inreg foo, i32) could only be produced when
sign-extended an i32. However, it can be produced by input such as:
define i64 @tricky_ashr(i64 %a, i64 %b) {
%1 = shl i64 %a, 32
%2 = ashr i64 %1, 32
%3 = ashr i64 %2, %b
ret i64 %3
}
It's important not to select sraw in the above case, because sraw only uses
bits lower 5 bits from the shift, while a shift of 32-63 would be valid.
Similarly, the patterns for srlw assumed (and foo, 0xffffffff) would only be
produced when zero-extending a value that was originally i32 in LLVM IR. This
is obviously incorrect.
This patch removes the SLLW/SRLW/SRAW shift patterns for the time being and
adds test cases that would demonstrate a miscompile if the incorrect patterns
were re-added.
llvm-svn: 348067
2018-12-01 13:00:00 +08:00
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
|
|
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
|
|
|
|
; RUN: | FileCheck %s -check-prefix=RV64I
|
|
|
|
|
|
|
|
; These tests must not compile to sllw/srlw/sraw, as this would be semantically
|
|
|
|
; incorrect in the case that %b holds a value between 32 and 63. Selection
|
|
|
|
; patterns might make the mistake of assuming that a (sext_inreg foo, i32) can
|
|
|
|
; only be produced when sign-extending an i32 type.
|
|
|
|
|
2019-05-23 20:43:13 +08:00
|
|
|
define i64 @tricky_shl(i64 %a, i64 %b) nounwind {
|
[RISCV] Remove RV64I SLLW/SRLW/SRAW patterns and add new test cases
As noted by Eli Friedman <https://reviews.llvm.org/D52977?id=168629#1315291>,
the RV64I shift patterns for SLLW/SRLW/SRAW make some incorrect assumptions.
SRAW assumed that (sext_inreg foo, i32) could only be produced when
sign-extended an i32. However, it can be produced by input such as:
define i64 @tricky_ashr(i64 %a, i64 %b) {
%1 = shl i64 %a, 32
%2 = ashr i64 %1, 32
%3 = ashr i64 %2, %b
ret i64 %3
}
It's important not to select sraw in the above case, because sraw only uses
bits lower 5 bits from the shift, while a shift of 32-63 would be valid.
Similarly, the patterns for srlw assumed (and foo, 0xffffffff) would only be
produced when zero-extending a value that was originally i32 in LLVM IR. This
is obviously incorrect.
This patch removes the SLLW/SRLW/SRAW shift patterns for the time being and
adds test cases that would demonstrate a miscompile if the incorrect patterns
were re-added.
llvm-svn: 348067
2018-12-01 13:00:00 +08:00
|
|
|
; RV64I-LABEL: tricky_shl:
|
|
|
|
; RV64I: # %bb.0:
|
|
|
|
; RV64I-NEXT: sll a0, a0, a1
|
|
|
|
; RV64I-NEXT: sext.w a0, a0
|
|
|
|
; RV64I-NEXT: ret
|
|
|
|
%1 = shl i64 %a, %b
|
|
|
|
%2 = shl i64 %1, 32
|
|
|
|
%3 = ashr i64 %2, 32
|
|
|
|
ret i64 %3
|
|
|
|
}
|
|
|
|
|
2019-05-23 20:43:13 +08:00
|
|
|
define i64 @tricky_lshr(i64 %a, i64 %b) nounwind {
|
[RISCV] Remove RV64I SLLW/SRLW/SRAW patterns and add new test cases
As noted by Eli Friedman <https://reviews.llvm.org/D52977?id=168629#1315291>,
the RV64I shift patterns for SLLW/SRLW/SRAW make some incorrect assumptions.
SRAW assumed that (sext_inreg foo, i32) could only be produced when
sign-extended an i32. However, it can be produced by input such as:
define i64 @tricky_ashr(i64 %a, i64 %b) {
%1 = shl i64 %a, 32
%2 = ashr i64 %1, 32
%3 = ashr i64 %2, %b
ret i64 %3
}
It's important not to select sraw in the above case, because sraw only uses
bits lower 5 bits from the shift, while a shift of 32-63 would be valid.
Similarly, the patterns for srlw assumed (and foo, 0xffffffff) would only be
produced when zero-extending a value that was originally i32 in LLVM IR. This
is obviously incorrect.
This patch removes the SLLW/SRLW/SRAW shift patterns for the time being and
adds test cases that would demonstrate a miscompile if the incorrect patterns
were re-added.
llvm-svn: 348067
2018-12-01 13:00:00 +08:00
|
|
|
; RV64I-LABEL: tricky_lshr:
|
|
|
|
; RV64I: # %bb.0:
|
|
|
|
; RV64I-NEXT: slli a0, a0, 32
|
|
|
|
; RV64I-NEXT: srli a0, a0, 32
|
|
|
|
; RV64I-NEXT: srl a0, a0, a1
|
|
|
|
; RV64I-NEXT: ret
|
|
|
|
%1 = and i64 %a, 4294967295
|
|
|
|
%2 = lshr i64 %1, %b
|
|
|
|
ret i64 %2
|
|
|
|
}
|
|
|
|
|
2019-05-23 20:43:13 +08:00
|
|
|
define i64 @tricky_ashr(i64 %a, i64 %b) nounwind {
|
[RISCV] Remove RV64I SLLW/SRLW/SRAW patterns and add new test cases
As noted by Eli Friedman <https://reviews.llvm.org/D52977?id=168629#1315291>,
the RV64I shift patterns for SLLW/SRLW/SRAW make some incorrect assumptions.
SRAW assumed that (sext_inreg foo, i32) could only be produced when
sign-extended an i32. However, it can be produced by input such as:
define i64 @tricky_ashr(i64 %a, i64 %b) {
%1 = shl i64 %a, 32
%2 = ashr i64 %1, 32
%3 = ashr i64 %2, %b
ret i64 %3
}
It's important not to select sraw in the above case, because sraw only uses
bits lower 5 bits from the shift, while a shift of 32-63 would be valid.
Similarly, the patterns for srlw assumed (and foo, 0xffffffff) would only be
produced when zero-extending a value that was originally i32 in LLVM IR. This
is obviously incorrect.
This patch removes the SLLW/SRLW/SRAW shift patterns for the time being and
adds test cases that would demonstrate a miscompile if the incorrect patterns
were re-added.
llvm-svn: 348067
2018-12-01 13:00:00 +08:00
|
|
|
; RV64I-LABEL: tricky_ashr:
|
|
|
|
; RV64I: # %bb.0:
|
|
|
|
; RV64I-NEXT: sext.w a0, a0
|
|
|
|
; RV64I-NEXT: sra a0, a0, a1
|
|
|
|
; RV64I-NEXT: ret
|
|
|
|
%1 = shl i64 %a, 32
|
|
|
|
%2 = ashr i64 %1, 32
|
|
|
|
%3 = ashr i64 %2, %b
|
|
|
|
ret i64 %3
|
|
|
|
}
|