Skip to content

Commit fe6ae81

Browse files
committed
[InstCombine] Fix vscale zext/sext optimization when vscale_range is unbounded.
According to the LangRef, a (vscale_range) value of 0 means unbounded. This patch additionally cleans up the test file vscale_sext_and_zext.ll.
1 parent e57e1e4 commit fe6ae81

File tree

2 files changed

+68
-45
lines changed

2 files changed

+68
-45
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,7 @@ Instruction *InstCombinerImpl::visitZExt(ZExtInst &CI) {
13681368
.getVScaleRangeArgs()
13691369
.second;
13701370
unsigned TypeWidth = Src->getType()->getScalarSizeInBits();
1371-
if (Log2_32(MaxVScale) < TypeWidth) {
1371+
if (MaxVScale > 0 && Log2_32(MaxVScale) < TypeWidth) {
13721372
Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
13731373
return replaceInstUsesWith(CI, VScale);
13741374
}
@@ -1625,8 +1625,7 @@ Instruction *InstCombinerImpl::visitSExt(SExtInst &CI) {
16251625
->getFnAttribute(Attribute::VScaleRange)
16261626
.getVScaleRangeArgs()
16271627
.second;
1628-
unsigned TypeWidth = Src->getType()->getScalarSizeInBits();
1629-
if (Log2_32(MaxVScale) < (TypeWidth - 1)) {
1628+
if (MaxVScale > 0 && Log2_32(MaxVScale) < (SrcBitSize - 1)) {
16301629
Value *VScale = Builder.CreateVScale(ConstantInt::get(DestTy, 1));
16311630
return replaceInstUsesWith(CI, VScale);
16321631
}

llvm/test/Transforms/InstCombine/vscale_sext_and_zext.ll

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,109 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt < %s -instcombine -S | FileCheck %s
33

4-
define i64 @vscale_SExt_i32toi64() #0 {
5-
; CHECK: entry:
6-
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
7-
; CHECK-NEXT: ret i64 [[TMP0]]
8-
entry:
9-
%0 = call i32 @llvm.vscale.i32()
10-
%1 = sext i32 %0 to i64
11-
ret i64 %1
12-
}
4+
;
5+
; Sign-extend
6+
;
137

14-
define i32 @vscale_SExt_i8toi32() #0 {
15-
; CHECK: entry:
8+
define i32 @vscale_SExt_i8toi32() vscale_range(0, 127) {
9+
; CHECK-LABEL: @vscale_SExt_i8toi32(
10+
; CHECK-NEXT: entry:
1611
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.vscale.i32()
1712
; CHECK-NEXT: ret i32 [[TMP0]]
13+
;
1814
entry:
1915
%0 = call i8 @llvm.vscale.i8()
2016
%1 = sext i8 %0 to i32
2117
ret i32 %1
2218
}
2319

24-
25-
define i32 @vscale_SExt_i8toi32_poison() vscale_range(0, 192) {
26-
; CHECK: entry:
20+
define i32 @vscale_SExt_i8toi32_poison() vscale_range(0, 128) {
21+
; CHECK-LABEL: @vscale_SExt_i8toi32_poison(
22+
; CHECK-NEXT: entry:
2723
; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.vscale.i8()
2824
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[TMP0]] to i32
2925
; CHECK-NEXT: ret i32 [[TMP1]]
26+
;
3027
entry:
3128
%0 = call i8 @llvm.vscale.i8()
3229
%1 = sext i8 %0 to i32
3330
ret i32 %1
3431
}
3532

33+
;
34+
; Zero-extend
35+
;
3636

37-
38-
define i64 @vscale_ZExt_i32toi64() #0 {
39-
; CHECK: entry:
40-
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
41-
; CHECK-NEXT: ret i64 [[TMP0]]
37+
define i32 @vscale_ZExt_i8toi32() vscale_range(0, 128) {
38+
; CHECK-LABEL: @vscale_ZExt_i8toi32(
39+
; CHECK-NEXT: entry:
40+
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.vscale.i32()
41+
; CHECK-NEXT: ret i32 [[TMP0]]
42+
;
4243
entry:
43-
%0 = call i32 @llvm.vscale.i32()
44-
%1 = zext i32 %0 to i64
45-
ret i64 %1
44+
%0 = call i8 @llvm.vscale.i8()
45+
%1 = zext i8 %0 to i32
46+
ret i32 %1
4647
}
4748

48-
define i64 @vscale_ZExt_i1toi64() vscale_range(0, 1) {
49-
; CHECK: entry:
50-
; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
51-
; CHECK-NEXT: ret i64 [[TMP0]]
52-
entry:
53-
%0 = call i1 @llvm.vscale.i1()
54-
%1 = zext i1 %0 to i64
55-
ret i64 %1
49+
define i32 @vscale_ZExt_i8toi32_poison() vscale_range(0, 256) {
50+
; CHECK-LABEL: @vscale_ZExt_i8toi32_poison(
51+
; CHECK-NEXT: entry:
52+
; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.vscale.i8()
53+
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32
54+
; CHECK-NEXT: ret i32 [[TMP1]]
55+
;
56+
entry:
57+
%0 = call i8 @llvm.vscale.i8()
58+
%1 = zext i8 %0 to i32
59+
ret i32 %1
5660
}
5761

58-
define i32 @vscale_ZExt_i8toi32_poison() vscale_range(0, 1024) {
59-
; CHECK: entry:
62+
;
63+
; No vscale_range attribute
64+
;
65+
66+
define i32 @vscale_ZExt_i8toi32_unknown() {
67+
; CHECK-LABEL: @vscale_ZExt_i8toi32_unknown(
68+
; CHECK-NEXT: entry:
6069
; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.vscale.i8()
6170
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32
6271
; CHECK-NEXT: ret i32 [[TMP1]]
72+
;
6373
entry:
6474
%0 = call i8 @llvm.vscale.i8()
6575
%1 = zext i8 %0 to i32
6676
ret i32 %1
6777
}
6878

69-
define i32 @vscale_ZExt_i16toi32_unknown() {
70-
; CHECK: entry:
71-
; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.vscale.i16()
72-
; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[TMP0]] to i32
79+
;
80+
; unbounded vscale_range maximum (0)
81+
;
82+
83+
define i32 @vscale_SExt_i8toi32_unbounded() vscale_range(0, 0) {
84+
; CHECK-LABEL: @vscale_SExt_i8toi32_unbounded(
85+
; CHECK-NEXT: entry:
86+
; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.vscale.i8()
87+
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[TMP0]] to i32
7388
; CHECK-NEXT: ret i32 [[TMP1]]
89+
;
7490
entry:
75-
%0 = call i16 @llvm.vscale.i16()
76-
%1 = zext i16 %0 to i32
91+
%0 = call i8 @llvm.vscale.i8()
92+
%1 = sext i8 %0 to i32
7793
ret i32 %1
7894
}
7995

80-
attributes #0 = { vscale_range(0, 16) }
96+
define i32 @vscale_ZExt_i8toi32_unbounded() vscale_range(0, 0) {
97+
; CHECK-LABEL: @vscale_ZExt_i8toi32_unbounded(
98+
; CHECK-NEXT: entry:
99+
; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.vscale.i8()
100+
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32
101+
; CHECK-NEXT: ret i32 [[TMP1]]
102+
;
103+
entry:
104+
%0 = call i8 @llvm.vscale.i8()
105+
%1 = zext i8 %0 to i32
106+
ret i32 %1
107+
}
81108

82-
declare i1 @llvm.vscale.i1()
83109
declare i8 @llvm.vscale.i8()
84-
declare i16 @llvm.vscale.i16()
85-
declare i32 @llvm.vscale.i32()

0 commit comments

Comments
 (0)