179 lines · plain
1; RUN: llc < %s -mtriple=armv6-linux-gnueabi | FileCheck %s -check-prefix=CHECKELF2; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 | FileCheck %s -check-prefix=CHECKT2D3 4declare i16 @identity16(i16 returned %x)5declare i32 @identity32(i32 returned %x)6declare zeroext i16 @retzext16(i16 returned %x)7declare i16 @paramzext16(i16 zeroext returned %x)8declare zeroext i16 @bothzext16(i16 zeroext returned %x)9 10; The zeroext param attribute below is meant to have no effect11define i16 @test_identity(i16 zeroext %x) {12entry:13; CHECKELF-LABEL: test_identity:14; CHECKELF: mov [[SAVEX:r[0-9]+]], r015; CHECKELF: bl identity1616; CHECKELF: uxth r0, r017; CHECKELF: bl identity3218; CHECKELF: mov r0, [[SAVEX]]19; CHECKT2D-LABEL: test_identity:20; CHECKT2D: mov [[SAVEX:r[0-9]+]], r021; CHECKT2D: bl _identity1622; CHECKT2D: uxth r0, r023; CHECKT2D: bl _identity3224; CHECKT2D: mov r0, [[SAVEX]]25 %call = tail call i16 @identity16(i16 returned %x)26 %b = zext i16 %call to i3227 %call2 = tail call i32 @identity32(i32 returned %b)28 ret i16 %x29}30 31; FIXME: This ought not to require register saving but currently does because32; x is not considered equal to %call (see SelectionDAGBuilder.cpp)33define i16 @test_matched_ret(i16 %x) {34entry:35; CHECKELF-LABEL: test_matched_ret:36 37; This shouldn't be required38; CHECKELF: mov [[SAVEX:r[0-9]+]], r039 40; CHECKELF: bl retzext1641; CHECKELF-NOT: uxth r0, {{r[0-9]+}}42; CHECKELF: bl identity3243 44; This shouldn't be required45; CHECKELF: mov r0, [[SAVEX]]46 47; CHECKT2D-LABEL: test_matched_ret:48 49; This shouldn't be required50; CHECKT2D: mov [[SAVEX:r[0-9]+]], r051 52; CHECKT2D: bl _retzext1653; CHECKT2D-NOT: uxth r0, {{r[0-9]+}}54; CHECKT2D: bl _identity3255 56; This shouldn't be required57; CHECKT2D: mov r0, [[SAVEX]]58 59 %call = tail call i16 @retzext16(i16 returned %x)60 %b = zext i16 %call to i3261 %call2 = tail call i32 @identity32(i32 returned %b)62 ret i16 %x63}64 65define i16 @test_mismatched_ret(i16 %x) {66entry:67; CHECKELF-LABEL: test_mismatched_ret:68; CHECKELF: mov [[SAVEX:r[0-9]+]], r069; CHECKELF: bl retzext1670; CHECKELF: sxth r0, {{r[0-9]+}}71; CHECKELF: bl identity3272; CHECKELF: mov r0, [[SAVEX]]73; CHECKT2D-LABEL: test_mismatched_ret:74; CHECKT2D: mov [[SAVEX:r[0-9]+]], r075; CHECKT2D: bl _retzext1676; CHECKT2D: sxth r0, {{r[0-9]+}}77; CHECKT2D: bl _identity3278; CHECKT2D: mov r0, [[SAVEX]]79 %call = tail call i16 @retzext16(i16 returned %x)80 %b = sext i16 %call to i3281 %call2 = tail call i32 @identity32(i32 returned %b)82 ret i16 %x83}84 85define i16 @test_matched_paramext(i16 %x) {86entry:87; CHECKELF-LABEL: test_matched_paramext:88; CHECKELF: uxth r0, r089; CHECKELF: bl paramzext1690; CHECKELF: uxth r0, r091; CHECKELF: bl identity3292; CHECKELF: b paramzext1693; CHECKT2D-LABEL: test_matched_paramext:94; CHECKT2D: uxth r0, r095; CHECKT2D: bl _paramzext1696; CHECKT2D: uxth r0, r097; CHECKT2D: bl _identity3298; CHECKT2D: b.w _paramzext1699 %call = tail call i16 @paramzext16(i16 zeroext returned %x)100 %b = zext i16 %call to i32101 %call2 = tail call i32 @identity32(i32 returned %b)102 %call3 = tail call i16 @paramzext16(i16 zeroext returned %call)103 ret i16 %call3104}105 106; FIXME: This theoretically ought to optimize to exact same output as the107; version above, but doesn't currently (see SelectionDAGBuilder.cpp) 108define i16 @test_matched_paramext2(i16 %x) {109entry:110 111; Since there doesn't seem to be an unambiguous optimal selection and112; scheduling of uxth and mov instructions below in lieu of the 'returned'113; optimization, don't bother checking: just verify that the calls are made114; in the correct order as a basic correctness check.115 116; CHECKELF-LABEL: test_matched_paramext2:117; CHECKELF: bl paramzext16118; CHECKELF: bl identity32119; CHECKELF: b paramzext16120; CHECKT2D-LABEL: test_matched_paramext2:121; CHECKT2D: bl _paramzext16122; CHECKT2D: bl _identity32123; CHECKT2D: b.w _paramzext16124 %call = tail call i16 @paramzext16(i16 zeroext returned %x)125 126; Should make no difference if %x is used below rather than %call, but it does127 %b = zext i16 %x to i32128 129 %call2 = tail call i32 @identity32(i32 %b)130 %call3 = tail call i16 @paramzext16(i16 zeroext returned %call)131 ret i16 %call3132}133 134define i16 @test_matched_bothext(i16 %x) {135entry:136; CHECKELF-LABEL: test_matched_bothext:137; CHECKELF: uxth r0, r0138; CHECKELF: bl bothzext16139; CHECKELF-NOT: uxth r0, r0140 141; FIXME: Tail call should be OK here142; CHECKELF: bl identity32143 144; CHECKT2D-LABEL: test_matched_bothext:145; CHECKT2D: uxth r0, r0146; CHECKT2D: bl _bothzext16147; CHECKT2D-NOT: uxth r0, r0148 149; FIXME: Tail call should be OK here150; CHECKT2D: bl _identity32151 152 %call = tail call i16 @bothzext16(i16 zeroext returned %x)153 %b = zext i16 %x to i32154 %call2 = tail call i32 @identity32(i32 returned %b)155 ret i16 %call156}157 158define i16 @test_mismatched_bothext(i16 %x) {159entry:160; CHECKELF-LABEL: test_mismatched_bothext:161; CHECKELF: mov [[SAVEX:r[0-9]+]], r0162; CHECKELF: uxth r0, {{r[0-9]+}}163; CHECKELF: bl bothzext16164; CHECKELF: sxth r0, [[SAVEX]]165; CHECKELF: bl identity32166; CHECKELF: mov r0, [[SAVEX]]167; CHECKT2D-LABEL: test_mismatched_bothext:168; CHECKT2D: mov [[SAVEX:r[0-9]+]], r0169; CHECKT2D: uxth r0, {{r[0-9]+}}170; CHECKT2D: bl _bothzext16171; CHECKT2D: sxth r0, [[SAVEX]]172; CHECKT2D: bl _identity32173; CHECKT2D: mov r0, [[SAVEX]]174 %call = tail call i16 @bothzext16(i16 zeroext returned %x)175 %b = sext i16 %x to i32176 %call2 = tail call i32 @identity32(i32 returned %b)177 ret i16 %x178}179