[TypePromotion] Do not zero-extend getelementptr indexes since signed
A miscompilation issue has been addressed with improved handling. Fixes: https://github.com/llvm/llvm-project/issues/133928. Alive2: https://alive2.llvm.org/ce/z/gcMNvS.
This commit is contained in:
parent
fcead25550
commit
13faa81916
@ -806,10 +806,10 @@ bool TypePromotionImpl::TryToPromote(Value *V, unsigned PromotedWidth,
|
||||
if (CurrentVisited.count(V))
|
||||
return true;
|
||||
|
||||
// Ignore GEPs because they don't need promoting and the constant indices
|
||||
// will prevent the transformation.
|
||||
// Skip promoting GEPs as their indices should have already been
|
||||
// canonicalized to pointer width.
|
||||
if (isa<GetElementPtrInst>(V))
|
||||
return true;
|
||||
return false;
|
||||
|
||||
if (!isSupportedValue(V) || (shouldPromote(V) && !isLegalToPromote(V))) {
|
||||
LLVM_DEBUG(dbgs() << "IR Promotion: Can't handle: " << *V << "\n");
|
||||
|
41
llvm/test/CodeGen/AArch64/typepromotion-gep.ll
Normal file
41
llvm/test/CodeGen/AArch64/typepromotion-gep.ll
Normal file
@ -0,0 +1,41 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
||||
; RUN: opt -S -p typepromotion %s -o - | FileCheck %s
|
||||
|
||||
target triple = "arm64-apple-macosx15.0.0"
|
||||
|
||||
define i4 @gep_offset_signedness(ptr %ptr, i8 %offset, i1 %cond) {
|
||||
; CHECK-LABEL: define i4 @gep_offset_signedness(
|
||||
; CHECK-SAME: ptr [[PTR:%.*]], i8 [[OFFSET:%.*]], i1 [[COND:%.*]]) {
|
||||
; CHECK-NEXT: [[ENTRY:.*]]:
|
||||
; CHECK-NEXT: [[UNUSED_TRUNC:%.*]] = trunc i8 [[OFFSET]] to i4
|
||||
; CHECK-NEXT: [[PTR_IDX:%.*]] = getelementptr i8, ptr [[PTR]], i8 [[OFFSET]]
|
||||
; CHECK-NEXT: [[COND_2:%.*]] = icmp uge ptr [[PTR_IDX]], [[PTR]]
|
||||
; CHECK-NEXT: br i1 [[COND_2]], label %[[RETURN:.*]], label %[[ELSE:.*]]
|
||||
; CHECK: [[RETURN]]:
|
||||
; CHECK-NEXT: [[RET_VAL:%.*]] = phi i4 [ 0, %[[ELSE_RET:.*]] ], [ 1, %[[ENTRY]] ], [ 0, %[[ELSE]] ]
|
||||
; CHECK-NEXT: ret i4 [[RET_VAL]]
|
||||
; CHECK: [[ELSE]]:
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 0, 0
|
||||
; CHECK-NEXT: [[COND_3:%.*]] = icmp ult i8 [[ADD]], [[OFFSET]]
|
||||
; CHECK-NEXT: br i1 [[COND]], label %[[RETURN]], label %[[ELSE_RET]]
|
||||
; CHECK: [[ELSE_RET]]:
|
||||
; CHECK-NEXT: br label %[[RETURN]]
|
||||
;
|
||||
entry:
|
||||
%unused_trunc = trunc i8 %offset to i4
|
||||
%ptr.idx = getelementptr i8, ptr %ptr, i8 %offset
|
||||
%cond.2 = icmp uge ptr %ptr.idx, %ptr
|
||||
br i1 %cond.2, label %return, label %else
|
||||
|
||||
return: ; preds = %else.ret, %else, %entry
|
||||
%ret.val = phi i4 [ 0, %else.ret ], [ 1, %entry ], [ 0, %else ]
|
||||
ret i4 %ret.val
|
||||
|
||||
else: ; preds = %entry
|
||||
%add = add nuw i8 0, 0
|
||||
%cond.3 = icmp ult i8 %add, %offset
|
||||
br i1 %cond, label %return, label %else.ret
|
||||
|
||||
else.ret: ; preds = %else
|
||||
br label %return
|
||||
}
|
@ -237,25 +237,27 @@ define i16 @promote_arg_return(i16 zeroext %arg1, i16 zeroext %arg2, ptr %res) {
|
||||
define i16 @signext_bitcast_phi_select(i16 signext %start, ptr %in) {
|
||||
; CHECK-LABEL: signext_bitcast_phi_select:
|
||||
; CHECK: // %bb.0: // %entry
|
||||
; CHECK-NEXT: mov w8, #-1 // =0xffffffff
|
||||
; CHECK-NEXT: and w9, w0, #0xffff
|
||||
; CHECK-NEXT: cmp w8, w9, sxth
|
||||
; CHECK-NEXT: mov w9, #-1 // =0xffffffff
|
||||
; CHECK-NEXT: mov w10, #32768 // =0x8000
|
||||
; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
|
||||
; CHECK-NEXT: cmp w9, w0, sxth
|
||||
; CHECK-NEXT: b.lt .LBB6_3
|
||||
; CHECK-NEXT: .LBB6_1: // %if.then
|
||||
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: ldrh w0, [x1, w9, sxtw #1]
|
||||
; CHECK-NEXT: cmp w0, w9
|
||||
; CHECK-NEXT: sxth x8, w0
|
||||
; CHECK-NEXT: ldrh w8, [x1, x8, lsl #1]
|
||||
; CHECK-NEXT: cmp w8, w0, uxth
|
||||
; CHECK-NEXT: b.eq .LBB6_4
|
||||
; CHECK-NEXT: // %bb.2: // %if.else
|
||||
; CHECK-NEXT: // in Loop: Header=BB6_1 Depth=1
|
||||
; CHECK-NEXT: lsr w10, w9, #15
|
||||
; CHECK-NEXT: eor w10, w10, #0x1
|
||||
; CHECK-NEXT: add w9, w10, w9
|
||||
; CHECK-NEXT: cmp w8, w9, sxth
|
||||
; CHECK-NEXT: bic w8, w10, w0
|
||||
; CHECK-NEXT: add w0, w0, w8, lsr #15
|
||||
; CHECK-NEXT: cmp w9, w0, sxth
|
||||
; CHECK-NEXT: b.ge .LBB6_1
|
||||
; CHECK-NEXT: .LBB6_3:
|
||||
; CHECK-NEXT: mov w0, wzr
|
||||
; CHECK-NEXT: mov w8, wzr
|
||||
; CHECK-NEXT: .LBB6_4: // %exit
|
||||
; CHECK-NEXT: mov w0, w8
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
%const = bitcast i16 -1 to i16
|
||||
|
@ -293,28 +293,24 @@ define i16 @promote_arg_return(i16 zeroext %arg1, i16 zeroext %arg2, ptr %res) {
|
||||
define i16 @signext_bitcast_phi_select(i16 signext %start, ptr %in) {
|
||||
; CHECK-LABEL: @signext_bitcast_phi_select(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[START:%.*]] to i32
|
||||
; CHECK-NEXT: [[CONST:%.*]] = bitcast i16 -1 to i16
|
||||
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
||||
; CHECK: for.body:
|
||||
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[SELECT:%.*]], [[IF_ELSE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IDX]] to i16
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = phi i16 [ [[SELECT:%.*]], [[IF_ELSE:%.*]] ], [ [[START:%.*]], [[ENTRY:%.*]] ]
|
||||
; CHECK-NEXT: [[CMP_I:%.*]] = icmp sgt i16 [[TMP1]], [[CONST]]
|
||||
; CHECK-NEXT: br i1 [[CMP_I]], label [[EXIT:%.*]], label [[IF_THEN:%.*]]
|
||||
; CHECK: if.then:
|
||||
; CHECK-NEXT: [[IDX_NEXT:%.*]] = getelementptr i16, ptr [[IN:%.*]], i32 [[IDX]]
|
||||
; CHECK-NEXT: [[IDX_NEXT:%.*]] = getelementptr i16, ptr [[IN:%.*]], i16 [[TMP1]]
|
||||
; CHECK-NEXT: [[LD:%.*]] = load i16, ptr [[IDX_NEXT]], align 2
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[LD]] to i32
|
||||
; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i32 [[TMP2]], [[IDX]]
|
||||
; CHECK-NEXT: [[CMP1_I:%.*]] = icmp eq i16 [[LD]], [[TMP1]]
|
||||
; CHECK-NEXT: br i1 [[CMP1_I]], label [[EXIT]], label [[IF_ELSE]]
|
||||
; CHECK: if.else:
|
||||
; CHECK-NEXT: [[LOBIT:%.*]] = lshr i32 [[IDX]], 15
|
||||
; CHECK-NEXT: [[LOBIT_NOT:%.*]] = xor i32 [[LOBIT]], 1
|
||||
; CHECK-NEXT: [[SELECT]] = add nuw i32 [[LOBIT_NOT]], [[IDX]]
|
||||
; CHECK-NEXT: [[LOBIT:%.*]] = lshr i16 [[TMP1]], 15
|
||||
; CHECK-NEXT: [[LOBIT_NOT:%.*]] = xor i16 [[LOBIT]], 1
|
||||
; CHECK-NEXT: [[SELECT]] = add nuw i16 [[LOBIT_NOT]], [[TMP1]]
|
||||
; CHECK-NEXT: br label [[FOR_BODY]]
|
||||
; CHECK: exit:
|
||||
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[TMP2]], [[IF_THEN]] ], [ 0, [[FOR_BODY]] ]
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = trunc i32 [[RES]] to i16
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = phi i16 [ [[LD]], [[IF_THEN]] ], [ 0, [[FOR_BODY]] ]
|
||||
; CHECK-NEXT: ret i16 [[TMP3]]
|
||||
;
|
||||
entry:
|
||||
|
@ -4,20 +4,18 @@
|
||||
define void @phi_pointers(ptr %a, ptr %b, i8 zeroext %M, i8 zeroext %N) {
|
||||
; CHECK-LABEL: @phi_pointers(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[M:%.*]] to i32
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[N:%.*]] to i32
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[TMP0]], 1
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], 1
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[ADD]], [[TMP1]]
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[M:%.*]], 1
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i8 [[ADD]], 1
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[ADD]], [[N:%.*]]
|
||||
; CHECK-NEXT: [[BASE:%.*]] = select i1 [[CMP]], ptr [[A:%.*]], ptr [[B:%.*]]
|
||||
; CHECK-NEXT: [[OTHER:%.*]] = select i1 [[CMP]], ptr [[B]], ptr [[B]]
|
||||
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[BASE]], [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[AND]], [[ENTRY]] ], [ [[INC:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ [[AND]], [[ENTRY]] ], [ [[INC:%.*]], [[LOOP]] ]
|
||||
; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[PTR]], align 2
|
||||
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[IDX]], 1
|
||||
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i16, ptr [[PTR]], i32 [[INC]]
|
||||
; CHECK-NEXT: [[INC]] = add nuw nsw i8 [[IDX]], 1
|
||||
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i16, ptr [[PTR]], i8 [[INC]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[GEP]], [[OTHER]]
|
||||
; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
@ -47,11 +45,9 @@ exit:
|
||||
define void @phi_pointers_null(ptr %a, ptr %b, i8 zeroext %M, i8 zeroext %N) {
|
||||
; CHECK-LABEL: @phi_pointers_null(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[M:%.*]] to i32
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[N:%.*]] to i32
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[TMP0]], 1
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], 1
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[ADD]], [[TMP1]]
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[M:%.*]], 1
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i8 [[ADD]], 1
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[ADD]], [[N:%.*]]
|
||||
; CHECK-NEXT: [[BASE:%.*]] = select i1 [[CMP]], ptr [[A:%.*]], ptr [[B:%.*]]
|
||||
; CHECK-NEXT: [[OTHER:%.*]] = select i1 [[CMP]], ptr [[B]], ptr [[B]]
|
||||
; 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) {
|
||||
; CHECK-NEXT: br label [[LOOP]]
|
||||
; CHECK: loop:
|
||||
; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[BASE]], [[ENTRY:%.*]] ], [ null, [[FAIL]] ], [ [[GEP:%.*]], [[IF_THEN:%.*]] ]
|
||||
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[AND]], [[ENTRY]] ], [ 0, [[FAIL]] ], [ [[INC:%.*]], [[IF_THEN]] ]
|
||||
; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ [[AND]], [[ENTRY]] ], [ 0, [[FAIL]] ], [ [[INC:%.*]], [[IF_THEN]] ]
|
||||
; CHECK-NEXT: [[UNDEF:%.*]] = icmp eq ptr [[PTR]], undef
|
||||
; CHECK-NEXT: br i1 [[UNDEF]], label [[EXIT:%.*]], label [[IF_THEN]]
|
||||
; CHECK: if.then:
|
||||
; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[PTR]], align 2
|
||||
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[IDX]], 1
|
||||
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i16, ptr [[PTR]], i32 [[INC]]
|
||||
; CHECK-NEXT: [[INC]] = add nuw nsw i8 [[IDX]], 1
|
||||
; CHECK-NEXT: [[GEP]] = getelementptr inbounds i16, ptr [[PTR]], i8 [[INC]]
|
||||
; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[GEP]], [[OTHER]]
|
||||
; CHECK-NEXT: br i1 [[COND]], label [[EXIT]], label [[LOOP]]
|
||||
; CHECK: exit:
|
||||
|
Loading…
x
Reference in New Issue
Block a user