1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00
llvm-mirror/test/Transforms/SeparateConstOffsetFromGEP/test-add-sub-separation.ll
Drew Wock 161d927dda [SeparateConstOffsetFromGEP] Fix: sext(a) + sext(b) -> sext(a + b) matches add and sub instructions with one another
During the SeparateConstOffsetFromGEP pass, signed extensions are distributed
to the values that feed into them and then later recombined. The recombination
stage is somewhat problematic- it doesn't differ add and sub instructions
from another when matching the sext(a) +/- sext(b) -> sext(a +/- b) pattern
in some instances.

An example- the IR contains:
%unextendedA
%unextendedB
%subuAuB = unextendedA - unextendedB
%extA = extend A
%extB = extend B
%addeAeB = extA + extB

The problematic optimization will transform that into:

%unextendedA
%unextendedB
%subuAuB = unextendedA - unextendedB
%extA = extend A
%extB = extend B
%addeAeB = extend subuAuB ; Obviously not semantically equivalent to the IR input.

This patch fixes that.

Patch by Drew Wock <drew.wock@sas.com>
Differential Revision: https://reviews.llvm.org/D65967
2020-01-17 12:22:52 -05:00

32 lines
1.2 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -separate-const-offset-from-gep < %s | FileCheck %s
define void @matchingExtensions(i32* %ap, i32* %bp, i64* %result) {
; CHECK-LABEL: @matchingExtensions(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[AP:%.*]]
; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[BP:%.*]]
; CHECK-NEXT: [[EB:%.*]] = sext i32 [[B]] to i64
; CHECK-NEXT: [[SUBAB:%.*]] = sub nsw i32 [[A]], [[B]]
; CHECK-NEXT: [[EA:%.*]] = sext i32 [[A]] to i64
; CHECK-NEXT: [[ADDEAEB:%.*]] = add nsw i64 [[EA]], [[EB]]
; CHECK-NEXT: [[EXTSUB:%.*]] = sext i32 [[SUBAB]] to i64
; CHECK-NEXT: [[IDX:%.*]] = getelementptr i32, i32* [[AP]], i64 [[EXTSUB]]
; CHECK-NEXT: store i64 [[ADDEAEB]], i64* [[RESULT:%.*]]
; CHECK-NEXT: store i32 [[SUBAB]], i32* [[IDX]]
; CHECK-NEXT: ret void
;
entry:
%a = load i32, i32* %ap
%b = load i32, i32* %bp
%eb = sext i32 %b to i64
%subab = sub nsw i32 %a, %b
%ea = sext i32 %a to i64
%addeaeb = add nsw i64 %ea, %eb
%extsub = sext i32 %subab to i64
%idx = getelementptr i32, i32* %ap, i64 %extsub
store i64 %addeaeb, i64* %result
store i32 %subab, i32* %idx
ret void
}