Skip to content

Commit 13faa81

Browse files
[TypePromotion] Do not zero-extend getelementptr indexes since signed
A miscompilation issue has been addressed with improved handling. Fixes: #133928. Alive2: https://alive2.llvm.org/ce/z/gcMNvS.
1 parent fcead25 commit 13faa81

File tree

5 files changed

+75
-40
lines changed

5 files changed

+75
-40
lines changed

llvm/lib/CodeGen/TypePromotion.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -806,10 +806,10 @@ bool TypePromotionImpl::TryToPromote(Value *V, unsigned PromotedWidth,
806806
if (CurrentVisited.count(V))
807807
return true;
808808

809-
// Ignore GEPs because they don't need promoting and the constant indices
810-
// will prevent the transformation.
809+
// Skip promoting GEPs as their indices should have already been
810+
// canonicalized to pointer width.
811811
if (isa<GetElementPtrInst>(V))
812-
return true;
812+
return false;
813813

814814
if (!isSupportedValue(V) || (shouldPromote(V) && !isLegalToPromote(V))) {
815815
LLVM_DEBUG(dbgs() << "IR Promotion: Can't handle: " << *V << "\n");
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -p typepromotion %s -o - | FileCheck %s
3+
4+
target triple = "arm64-apple-macosx15.0.0"
5+
6+
define i4 @gep_offset_signedness(ptr %ptr, i8 %offset, i1 %cond) {
7+
; CHECK-LABEL: define i4 @gep_offset_signedness(
8+
; CHECK-SAME: ptr [[PTR:%.*]], i8 [[OFFSET:%.*]], i1 [[COND:%.*]]) {
9+
; CHECK-NEXT: [[ENTRY:.*]]:
10+
; CHECK-NEXT: [[UNUSED_TRUNC:%.*]] = trunc i8 [[OFFSET]] to i4
11+
; CHECK-NEXT: [[PTR_IDX:%.*]] = getelementptr i8, ptr [[PTR]], i8 [[OFFSET]]
12+
; CHECK-NEXT: [[COND_2:%.*]] = icmp uge ptr [[PTR_IDX]], [[PTR]]
13+
; CHECK-NEXT: br i1 [[COND_2]], label %[[RETURN:.*]], label %[[ELSE:.*]]
14+
; CHECK: [[RETURN]]:
15+
; CHECK-NEXT: [[RET_VAL:%.*]] = phi i4 [ 0, %[[ELSE_RET:.*]] ], [ 1, %[[ENTRY]] ], [ 0, %[[ELSE]] ]
16+
; CHECK-NEXT: ret i4 [[RET_VAL]]
17+
; CHECK: [[ELSE]]:
18+
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 0, 0
19+
; CHECK-NEXT: [[COND_3:%.*]] = icmp ult i8 [[ADD]], [[OFFSET]]
20+
; CHECK-NEXT: br i1 [[COND]], label %[[RETURN]], label %[[ELSE_RET]]
21+
; CHECK: [[ELSE_RET]]:
22+
; CHECK-NEXT: br label %[[RETURN]]
23+
;
24+
entry:
25+
%unused_trunc = trunc i8 %offset to i4
26+
%ptr.idx = getelementptr i8, ptr %ptr, i8 %offset
27+
%cond.2 = icmp uge ptr %ptr.idx, %ptr
28+
br i1 %cond.2, label %return, label %else
29+
30+
return: ; preds = %else.ret, %else, %entry
31+
%ret.val = phi i4 [ 0, %else.ret ], [ 1, %entry ], [ 0, %else ]
32+
ret i4 %ret.val
33+
34+
else: ; preds = %entry
35+
%add = add nuw i8 0, 0
36+
%cond.3 = icmp ult i8 %add, %offset
37+
br i1 %cond, label %return, label %else.ret
38+
39+
else.ret: ; preds = %else
40+
br label %return
41+
}

llvm/test/CodeGen/AArch64/typepromotion-phisret.ll

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -237,25 +237,27 @@ define i16 @promote_arg_return(i16 zeroext %arg1, i16 zeroext %arg2, ptr %res) {
237237
define i16 @signext_bitcast_phi_select(i16 signext %start, ptr %in) {
238238
; CHECK-LABEL: signext_bitcast_phi_select:
239239
; CHECK: // %bb.0: // %entry
240-
; CHECK-NEXT: mov w8, #-1 // =0xffffffff
241-
; CHECK-NEXT: and w9, w0, #0xffff
242-
; CHECK-NEXT: cmp w8, w9, sxth
240+
; CHECK-NEXT: mov w9, #-1 // =0xffffffff
241+
; CHECK-NEXT: mov w10, #32768 // =0x8000
242+
; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
243+
; CHECK-NEXT: cmp w9, w0, sxth
243244
; CHECK-NEXT: b.lt .LBB6_3
244245
; CHECK-NEXT: .LBB6_1: // %if.then
245246
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
246-
; CHECK-NEXT: ldrh w0, [x1, w9, sxtw #1]
247-
; CHECK-NEXT: cmp w0, w9
247+
; CHECK-NEXT: sxth x8, w0
248+
; CHECK-NEXT: ldrh w8, [x1, x8, lsl #1]
249+
; CHECK-NEXT: cmp w8, w0, uxth
248250
; CHECK-NEXT: b.eq .LBB6_4
249251
; CHECK-NEXT: // %bb.2: // %if.else
250252
; CHECK-NEXT: // in Loop: Header=BB6_1 Depth=1
251-
; CHECK-NEXT: lsr w10, w9, #15
252-
; CHECK-NEXT: eor w10, w10, #0x1
253-
; CHECK-NEXT: add w9, w10, w9
254-
; CHECK-NEXT: cmp w8, w9, sxth
253+
; CHECK-NEXT: bic w8, w10, w0
254+
; CHECK-NEXT: add w0, w0, w8, lsr #15
255+
; CHECK-NEXT: cmp w9, w0, sxth
255256
; CHECK-NEXT: b.ge .LBB6_1
256257
; CHECK-NEXT: .LBB6_3:
257-
; CHECK-NEXT: mov w0, wzr
258+
; CHECK-NEXT: mov w8, wzr
258259
; CHECK-NEXT: .LBB6_4: // %exit
260+
; CHECK-NEXT: mov w0, w8
259261
; CHECK-NEXT: ret
260262
entry:
261263
%const = bitcast i16 -1 to i16

llvm/test/Transforms/TypePromotion/ARM/phis-ret.ll

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -293,28 +293,24 @@ define i16 @promote_arg_return(i16 zeroext %arg1, i16 zeroext %arg2, ptr %res) {
293293
define i16 @signext_bitcast_phi_select(i16 signext %start, ptr %in) {
294294
; CHECK-LABEL: @signext_bitcast_phi_select(
295295
; CHECK-NEXT: entry:
296-
; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[START:%.*]] to i32
297296
; CHECK-NEXT: [[CONST:%.*]] = bitcast i16 -1 to i16
298297
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
299298
; CHECK: for.body:
300-
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[SELECT:%.*]], [[IF_ELSE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
301-
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IDX]] to i16
299+
; CHECK-NEXT: [[TMP1:%.*]] = phi i16 [ [[SELECT:%.*]], [[IF_ELSE:%.*]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
302300
; CHECK-NEXT: [[CMP_I:%.*]] = icmp sgt i16 [[TMP1]], [[CONST]]
303301
; CHECK-NEXT: br i1 [[CMP_I]], label [[EXIT:%.*]], label [[IF_THEN:%.*]]
304302
; CHECK: if.then:
305-
; CHECK-NEXT: [[IDX_NEXT:%.*]] = getelementptr i16, ptr [[IN:%.*]], i32 [[IDX]]
303+
; CHECK-NEXT: [[IDX_NEXT:%.*]] = getelementptr i16, ptr [[IN:%.*]], i16 [[TMP1]]
306304
; CHECK-NEXT: [[LD:%.*]] = load i16, ptr [[IDX_NEXT]], align 2
307-
; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[LD]] to i32
308-
; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i32 [[TMP2]], [[IDX]]
305+
; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i16 [[LD]], [[TMP1]]
309306
; CHECK-NEXT: br i1 [[CMP1_I]], label [[EXIT]], label [[IF_ELSE]]
310307
; CHECK: if.else:
311-
; CHECK-NEXT: [[LOBIT:%.*]] = lshr i32 [[IDX]], 15
312-
; CHECK-NEXT: [[LOBIT_NOT:%.*]] = xor i32 [[LOBIT]], 1
313-
; CHECK-NEXT: [[SELECT]] = add nuw i32 [[LOBIT_NOT]], [[IDX]]
308+
; CHECK-NEXT: [[LOBIT:%.*]] = lshr i16 [[TMP1]], 15
309+
; CHECK-NEXT: [[LOBIT_NOT:%.*]] = xor i16 [[LOBIT]], 1
310+
; CHECK-NEXT: [[SELECT]] = add nuw i16 [[LOBIT_NOT]], [[TMP1]]
314311
; CHECK-NEXT: br label [[FOR_BODY]]
315312
; CHECK: exit:
316-
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[TMP2]], [[IF_THEN]] ], [ 0, [[FOR_BODY]] ]
317-
; CHECK-NEXT: [[TMP3:%.*]] = trunc i32 [[RES]] to i16
313+
; CHECK-NEXT: [[TMP3:%.*]] = phi i16 [ [[LD]], [[IF_THEN]] ], [ 0, [[FOR_BODY]] ]
318314
; CHECK-NEXT: ret i16 [[TMP3]]
319315
;
320316
entry:

llvm/test/Transforms/TypePromotion/ARM/pointers.ll

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,18 @@
44
define void @phi_pointers(ptr %a, ptr %b, i8 zeroext %M, i8 zeroext %N) {
55
; CHECK-LABEL: @phi_pointers(
66
; CHECK-NEXT: entry:
7-
; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[M:%.*]] to i32
8-
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[N:%.*]] to i32
9-
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[TMP0]], 1
10-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], 1
11-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[ADD]], [[TMP1]]
7+
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[M:%.*]], 1
8+
; CHECK-NEXT: [[AND:%.*]] = and i8 [[ADD]], 1
9+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[ADD]], [[N:%.*]]
1210
; CHECK-NEXT: [[BASE:%.*]] = select i1 [[CMP]], ptr [[A:%.*]], ptr [[B:%.*]]
1311
; CHECK-NEXT: [[OTHER:%.*]] = select i1 [[CMP]], ptr [[B]], ptr [[B]]
1412
; CHECK-NEXT: br label [[LOOP:%.*]]
1513
; CHECK: loop:
1614
; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[BASE]], [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
17-
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[AND]], [[ENTRY]] ], [ [[INC:%.*]], [[LOOP]] ]
15+
; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ [[AND]], [[ENTRY]] ], [ [[INC:%.*]], [[LOOP]] ]
1816
; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[PTR]], align 2
19-
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[IDX]], 1
20-
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i16, ptr [[PTR]], i32 [[INC]]
17+
; CHECK-NEXT: [[INC]] = add nuw nsw i8 [[IDX]], 1
18+
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i16, ptr [[PTR]], i8 [[INC]]
2119
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[GEP]], [[OTHER]]
2220
; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]
2321
; CHECK: exit:
@@ -47,11 +45,9 @@ exit:
4745
define void @phi_pointers_null(ptr %a, ptr %b, i8 zeroext %M, i8 zeroext %N) {
4846
; CHECK-LABEL: @phi_pointers_null(
4947
; CHECK-NEXT: entry:
50-
; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[M:%.*]] to i32
51-
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[N:%.*]] to i32
52-
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[TMP0]], 1
53-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], 1
54-
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[ADD]], [[TMP1]]
48+
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[M:%.*]], 1
49+
; CHECK-NEXT: [[AND:%.*]] = and i8 [[ADD]], 1
50+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[ADD]], [[N:%.*]]
5551
; CHECK-NEXT: [[BASE:%.*]] = select i1 [[CMP]], ptr [[A:%.*]], ptr [[B:%.*]]
5652
; CHECK-NEXT: [[OTHER:%.*]] = select i1 [[CMP]], ptr [[B]], ptr [[B]]
5753
; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq ptr [[BASE]], [[OTHER]]
@@ -60,13 +56,13 @@ define void @phi_pointers_null(ptr %a, ptr %b, i8 zeroext %M, i8 zeroext %N) {
6056
; CHECK-NEXT: br label [[LOOP]]
6157
; CHECK: loop:
6258
; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[BASE]], [[ENTRY:%.*]] ], [ null, [[FAIL]] ], [ [[GEP:%.*]], [[IF_THEN:%.*]] ]
63-
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[AND]], [[ENTRY]] ], [ 0, [[FAIL]] ], [ [[INC:%.*]], [[IF_THEN]] ]
59+
; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ [[AND]], [[ENTRY]] ], [ 0, [[FAIL]] ], [ [[INC:%.*]], [[IF_THEN]] ]
6460
; CHECK-NEXT: [[UNDEF:%.*]] = icmp eq ptr [[PTR]], undef
6561
; CHECK-NEXT: br i1 [[UNDEF]], label [[EXIT:%.*]], label [[IF_THEN]]
6662
; CHECK: if.then:
6763
; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[PTR]], align 2
68-
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[IDX]], 1
69-
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i16, ptr [[PTR]], i32 [[INC]]
64+
; CHECK-NEXT: [[INC]] = add nuw nsw i8 [[IDX]], 1
65+
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i16, ptr [[PTR]], i8 [[INC]]
7066
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[GEP]], [[OTHER]]
7167
; CHECK-NEXT: br i1 [[COND]], label [[EXIT]], label [[LOOP]]
7268
; CHECK: exit:

0 commit comments

Comments
 (0)